我们可以关闭终结器吗?

由于几乎没有什么保证关于什么时候,甚至终结器运行和终结器现在几乎被认为是气味 – 有没有办法说服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的代码:-)。