我们的团队有一个Java进程正在运行(在64位服务器OpenJDK 1.8.0_171-b10上),其中发生了一些无法解释的事情,涉及(装箱的)Long
对象的值。我们创建了一个堆转储以使用jhat
进行分析,这里确实发生了一些奇怪的事情。
正在运行jhat
,我们发出以下OQL查询之一:
select l from java.lang.Long l where l.value.toString().equals("20180919141719600")
select l from java.lang.Long l where l.value == 20180919141719600
两者都导致返回相同的三个对象。但是,当我们检查对象时,这三个对象在value
中具有不同的值,并且都不等于20180919141719600
。
这本身困扰着我们,是我们问题的核心。
此外,我们可以使情况变得更加有趣。似乎正在运行的Java代码使用实际值(正如我们在jhat
对象的value
字段的Long
字段中看到的那样),因为JSON序列化是因为REST端点返回了值20180919141719600
。这表明这两个值实际上都在内存中(和堆转储中),以及JSON序列化(使用Jackson)在某种程度上与jhat
在运行OQL查询时所做的操作完全不同。
分析这种情况的下一步是什么?