我们可以关闭终结器吗?
由于几乎没有什么保证关于什么时候,甚至终结器运行和终结器现在几乎被认为是气味 – 有没有办法说服JVM完全跳过所有的终结过程?
我问,因为我们有一个庞大的应用程序,当移动到一个较新的JVM(不确定在这个阶段)是什么看起来非常像终结者的已知问题(抛出exception,因此非常慢的GC) 。
添加
有关Java内存泄漏故障排除的讨论:终结? 建议在终结器中抛出exception时出现主要问题,因为这会大大减慢终结过程。
当内存变低并且堆转储的分析显示大量的Finalizer
对象(超过10,000,000)时,我的问题显示为急剧减速 – 向我表明减速可能是他们的错,因为他们正在推迟GC。 显然我可能是错的。
我没有权力要求重构。
有没有办法说服JVM完全跳过所有的终结过程?
一句话
但除非你的大部分对象都有finalize
方法和/或finalize
方法特别昂贵,我认为它们不太可能使GC“非常慢”。 我希望问题是别的。
我建议您打开GC日志记录,尝试更好地了解实际情况。
但我也同意,从长远来看,重构代码以摆脱finalize()
方法可能是一件好事。 (极少数情况下使用finalize
确实是最佳解决方案。)
更新 – 你的新证据非常有说服力,但不是certificate!
我没有权力要求重构。
然后,我建议你把证据放在那些做的人脚下:-)。
或者,您可以向可疑的finalize
方法添加exception处理程序,以查看它们是否抛出exception。 (如果是,那么改变它们以避免抛出exception……)
但最重要的是,如果最终确定是您的性能问题的真正原因,那么解决它们的最佳(也可能是唯一的)方法是更改代码。
可以抑制某些对象的最终化。 一位评论者指出,它不需要字节码操作。
此处描述了该过程,并提供了源代码。 java.lang.ref.Finalizer
类负责维护尚未最终确定的对象列表。 要禁止最终确定您感兴趣的对象,只需使用reflectionAPI获取字段lock
,迭代Finalizer类维护的最终链接列表,并从此列表中删除您的对象。
我已经尝试过这种方法来安全地实例化自定义序列化对象,同时绕过构造函数调用,并避免在使用普通GC调用终结器时出现问题。 在应用此方法之前,我的JVM会破坏终结器线程中的硬错误; 因为应用这种方法不会发生故障。
你不能在java中关闭finalizer
,但你所能做的就是编写有助于GC的代码:-)。