未调用finalize方法时如何记录?

时间:2019-11-08 17:00:21

标签: java java-8

我没有在应用程序中使用finalize方法,但是这个问题出于好奇。

假定类中有finalize方法,我想记录一条警告消息,提示未调用finalize。

如何执行此操作?

任何提示?

2 个答案:

答案 0 :(得分:1)

两种可能性-无论哪种情况,都需要一个单例集合。

1)构造每个对象时,将一个唯一的键(字符串)标识该对象-(但不是对象本身!)到集合中。调用终结器时,将其密钥从集合中删除。

在任何给定时间,集合中都有未完成的实例。

2)好吧,如果您确实愿意,可以将对象本身添加到集合中,但是该集合必须是正确引用类的集合。这比较困难,需要做一点研究-查看参考类(WeakReference / PhantomReference / ??)。我已经有好几年没有看过它们了,忘记了到底是哪个做的,但这正是Reference类所做的工作。

请注意2,我认为遍历参考集合可能会使死的类复活或阻止收集。

这两个警告的原因是,如果您将引用存储在普通集合中,则它将永远不符合收集条件,因此不会调用终结器。

答案 1 :(得分:0)

根据JLS 12.6. Finalization of Class Instances,JVM保证在处置对象之前将调用该方法:

  

Java编程语言没有指定终结器被调用的时间,只是说它将在重用对象的存储之前发生。

您正试图证明JVM不遵循JLS,这将是一个错误。

查看Azul Zulu OpenJDK 11的源代码,我们可以看到终结是通过java.lang.ref.Finalizer对象运行的,而该对象又使用jdk.internal.misc.JavaLangAccess.invokeFinalize(Object)方法来调用Object.finalize()

JavaLangAccess获得

jdk.internal.misc.SharedSecrets实例,该实例允许设置JavaLangAccess的自定义实例。也许您可以使用JavaLangAccess方法中的其他日志记录来创建自己的invokeFinalize()实例?