0

我想以粗体理解以下声明。这是什么意思?(链接

覆盖的对象finalize()现在必须在至少两个单独的垃圾收集周期中被确定为垃圾才能被收集。当第一个循环确定它是垃圾时,它就有资格进行终结。由于对象在最终确定期间“复活”的可能性(很小,但不幸的是真实的),垃圾收集器必须再次运行,然后才能实际删除对象。并且因为终结可能没有及时发生,所以在对象等待终结时可能发生了任意数量的垃圾回收周期。这可能意味着实际清理垃圾对象的严重延迟,这就是为什么OutOfMemoryError即使大部分堆都是垃圾也可以获得 s 的原因。

幻影参考解决了什么

使用 PhantomReference,这种情况是不可能的——当 PhantomReference 入队时,绝对没有办法获得指向现在已死对象的指针(这很好,因为它不再在内存中)。因为 PhantomReference 不能用于复活一个对象,所以可以在第一个垃圾回收周期中立即清理该对象,在该周期中发现它是幻影可访问的。

请帮助我了解问题和解决方案

谢谢

4

1 回答 1

1

与普遍的看法相反,当它们的关联对象被垃圾收集时,finalize方法不会被触发,而是当它们的关联对象垃圾收集但它们的非默认finalize方法存在时。在系统可以 100% 确定不会存在对它们的引用之前,对象实际上不能被垃圾收集,但是运行finalize方法的行为会创建对相关对象的强根引用,该引用至少会存在到方法退出. 如果在执行期间对finalize对象的引用被存储在其他地方,则该引用可能会无限期地继续存在。因此,没有对象finalized方法将被调用,并且该对象持有直接或间接强引用的任何其他对象都不能被收集,直到该finalize方法运行并且下一个 GC 循环确认不再存在对该对象的引用。

该类PhantomReference用于封装不同的范例:与其保持对象处于活动状态以便系统可以通知它它已被放弃并且它仍然活动的唯一原因是它可以接收放弃通知,需要清理的对象应该创建辅助对象来处理他们放弃的通知。如果辅助对象避免保留对它们不“拥有”的任何外部对象的引用,它们的存在不会干扰其父对象或父对象直接或间接引用的其他对象的集合。辅助对象通常不会保存足够的信息来让它们“做很多事情”,但这很好,因为它们不应该做很多事情。反而,

于 2015-07-13T18:50:11.400 回答