【发布时间】:2016-07-28 11:54:03
【问题描述】:
我已经阅读了很多关于终结器如何工作的文章。这是我的理解:如果一个类实现了 finalize 方法,Jvm 将创建一个 Finalizer 实例作为该对象的看门狗。
当 GC 运行时,它会标记要释放的对象并将它们添加到引用队列中,然后终结器线程将从队列中挑选这些对象并执行它们的 finalize 方法。
我的问题是:如何从堆转储中找到由于某种原因没有完成 finalize 方法并开始堆积引用队列的对象?
参考队列是否按特定顺序排列?
【问题讨论】:
-
只是想知道:你的终结器方法在做什么?为什么你有这么多对象想要使用一种方法,至少在理论上,没有人应该依赖?
-
从源代码看来,ReferenceQueue 就像一个 List 一样工作——它包含 Reference 对象,每个 Reference 都指向下一个 Reference。也许第一个对象就是你需要的。也许您应该尝试在 finalize 方法上添加方面并添加一些日志记录(例如为 xxx 调用 Finalize;Finalize 已完成) - 行中的最后一个条目将指向已开始完成但 finalize 未完成的对象。
-
我可能会另辟蹊径,对具有
finalize()的非平凡实现的类执行文本搜索 - 您的代码库中是否有太多候选对象? -
@Hulk GC 不运行终结器。请参阅
java.lang.ref.Reference类和嵌套的ReferenceHandler类。 GC 只添加对静态字段pending的引用。所有其他工作都在 Reference Handler 和 Finalizer 线程中的 java 代码中完成 -
@commit-man 公平点。删除了不正确的评论。我想我把它弄混了,因为我刚刚阅读了finalize 中的措辞:“当垃圾收集器确定不再有对该对象的引用时,由垃圾收集器在对象上调用。”