java - 对象未被终结且 Finalizer 线程未执行任何操作

标签 java garbage-collection out-of-memory finalize

在我们的服务器上,我们开始遇到 OutOfMemoryError 问题。我们使用 Eclipse Memory Analysis 分析了堆转储,发现有许多对象被保留以进行终结(大约占堆的 2/3):

enter image description here

我们发现,它可能是一些 finalize() 方法阻塞。我发现了几个关于这个问题的错误报告(herehere),它总是在 Finalizer 线程堆栈中表现出来,它在某处被阻塞。但在我们的例子中,这个线程正在等待:

"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)

编辑:

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

最后,我们怀疑是 JVM bug,从 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自动更新后出现的,但我们也无法确认。我们找不到相关的错误报告。

关于java - 对象未被终结且 Finalizer 线程未执行任何操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22243487/

相关文章:

java - 像 UTC 一样解析 ISO 8601 字符串本地日期时间

java - 不能在 Java 中分割一行

java - 调用 onClick 时为 "OutOfMemoryError"(崩溃报告)

java - PermGen 以 99% 的速度颠簸,但离 MaxPermSize 还很远

java - JVM 内存不足

解码位图流时Android应用程序OutOfMemoryError

android - 内存不足错误 viewpager + imageView

Java 未签名 Applet - 传递 VM 参数 "java.security.policy"被忽略?

java - 当网格列值为空时如何显示默认值?

java - 使用 7mb RAM 的 Android FinalizerReference