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线程等待下一个对象的原因?我们是否正确分析了堆转储?
谢谢你的所有答案.
我们认为它与 OpenJDK 版本 1.6.0_30 有关。升级到Oracle JDK 1.7.0_51后,问题消失。而且很可能是在openJDK自动更新后出现的,但我们也无法确认这一点。我们找不到相关的错误报告。