对象没有最终确定,Finalizer线程没有做任何事情

Oli*_*liv 7 java garbage-collection finalize out-of-memory

在我们的服务器上,我们开始遇到问题OutOfMemoryError.我们使用Eclipse Memory Analysis分析了堆转储,并发现许多对象都要进行最终化(约占堆的2/3):

在此输入图像描述

我们发现,它可能是一些finalize()方法阻塞.我发现了几个关于这个问题的bug报告(这里这里),它总是在Finalizer线程堆栈中表现出来,它在某个地方被阻塞了.但在我们的例子中,这个帖子是WAITING:

"Finalizer" daemon prio=10 tid=0x43e1e000 nid=0x3ff in Object.wait() [0x43dfe000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x4fe053e8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133)
        - locked <0x4fe053e8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)
Run Code Online (Sandbox Code Playgroud)

编辑:

然后我们尝试添加-XX:+UseConcMarkSweepGC,但没有成功,只有OutOfMemoryErrors 的频率减少,所以我们首先认为它有所帮助.

最后,我们怀疑JVM错误并从OpenJDK 1.6.0_30升级到Oracle JDK 1.7.0_51,问题消失了(至少看起来如此,在过去4小时内使用的堆没有增长).我们不记得finalize方法有任何变化,我们也没有升级任何库,在那段时间里只有很小的发展.问题不会在我们的测试服务器上重现,具有相同的配置,除了它是64位JVM而生产服务器是32位.

问题是:什么可能是对象没有最终确定和Finalizer线程等待下一个对象的原因?我们是否正确分析了堆转储?

谢谢你的所有答案.

Oli*_*liv 1

我们认为它与 OpenJDK 版本 1.6.0_30 有关。升级到Oracle JDK 1.7.0_51后,问题消失。而且很可能是在openJDK自动更新后出现的,但我们也无法确认这一点。我们找不到相关的错误报告。