对象未被完成和终结器线程未执行任何操作。
对象未被完成和终结器线程未执行任何操作。
在我们的服务器上,我们开始出现OutOfMemoryError
的问题。我们使用Eclipse Memory Analysis分析了堆转储,并发现许多对象被保留以进行最终处理(堆的约2/3):\n\n我们发现,可能是某个finalize()方法阻塞了。我找到了几个关于这个问题的bug报告(这里或这里),它们总是在Finalizer线程堆栈中表现为被阻塞的状态。但在我们的情况下,这个线程是WAITING状态:\n
"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)
\n编辑:\n然后我们尝试添加-XX:+UseConcMarkSweepGC
,但没有成功,只是OutOfMemoryError
的频率减少了,所以我们最初以为它有帮助。\n最后,我们怀疑是JVM的bug,并从OpenJDK 1.6.0_30升级到Oracle JDK 1.7.0_51,问题消失了(至少看起来是这样,在过去的4个小时里,已使用的堆没有增长)。我们不记得finalize方法有任何更改,也没有升级任何库,那段时间只有一些小的开发。这个问题在我们的测试服务器上没有复现,配置相同,只是测试服务器是64位JVM,而生产服务器是32位。\n问题是:导致对象无法完成最终处理并使Finalizer
线程等待下一个对象的原因是什么?我们是否正确分析了堆转储?\n感谢所有的答案。
出现"Objects not being finalized and Finalizer thread not doing anything"问题的原因可能是在应用程序中引入了过多的对象进入finalizer队列,导致JVM无法跟上finalizer的处理速度。
解决这个问题的方法是减少对finalizer的使用。除非在非常有限的情况下,否则finalizer会带来更多问题,包括GC和内存开销。如果发现有待处理的finalization cleanup对象,那么说明构造了过多的可finalizable对象。
这个问题的出现可能与JDK版本有关。Oracle的Java 7引入了一种更高效的垃圾收集器,可能减轻了GC的负载,使得finalizer队列能够获得更多的处理时间。然而,无论是什么原因,正确的解决方法都是减少对finalizer的使用。
在这种情况下,由于服务器的平均CPU使用率约为5%,所以finalizer有足够的时间来执行其工作。因此,这可能不是问题的原因。
我们认为这个问题与OpenJDK版本1.6.0_30有关。在升级到Oracle JDK 1.7.0_51后,问题消失了。很可能是在OpenJDK的自动更新之后出现的,但我们无法确认这一点。我们找不到相关的错误报告。
这个问题的出现原因可能是由于OpenJDK版本1.6.0_30中的一个bug导致的。在该版本中,对象没有被正确地进行finalization(即垃圾回收处理)并且Finalizer线程没有执行任何操作。这可能导致内存泄漏和其他潜在的问题。
解决这个问题的方法是升级到Oracle JDK 1.7.0_51或更高版本。在这个版本中,该问题已经得到修复,对象可以正确地进行finalization并且Finalizer线程会执行相应的操作。通过升级JDK,我们可以解决这个问题并确保系统的稳定性。
下面是升级JDK的示例代码:
sudo apt-get update
sudo apt-get install oracle-java7-installer
请注意,升级JDK可能需要root权限,具体的安装步骤可能会因操作系统和发行版而有所不同。我们建议在升级之前备份所有重要的数据,并确保您正在使用可靠的源来获取JDK。
总结起来,当遇到"Objects not being finalized and Finalizer thread not doing anything"的问题时,我们可以通过升级到较新的JDK版本来解决。这将确保对象正确进行finalization并且Finalizer线程能够正常工作,从而避免可能的内存泄漏和其他潜在问题。