【问题标题】:Why we are obliged to clear a PhantomReference manually?为什么我们必须手动清除 PhantomReference?
【发布时间】:2019-08-10 04:07:30
【问题描述】:

来自javadoc

与软引用和弱引用不同,幻像引用在排队时不会被垃圾收集器自动清除。可以通过幻像引用访问的对象将保持不变,直到所有此类引用都被清除或自身变得不可访问。

一旦放入 ReferenceQueue,幻象链接的引用对象就被认为是“死的”,程序员的代码无论如何都无法访问它。那么为什么 JVM 等待手动 clear() 呢?对于弱参考,它不会。

【问题讨论】:

  • 这在 Java 9 之后发生了变化,请参阅 herehere。幻像引用现在像软引用和弱引用一样被清除,另见this answer 的第二部分。

标签: java garbage-collection phantom-reference


【解决方案1】:

his answer 中,当队列以null 给出时,关于PhantomReference 行为的相关问题,Holger 说:

“这个问题,更难回答,是为什么 PhantomReference 不会自动清除。文档只说幻影可达对象将保持不变,这是未清除的结果,但是没有解释为什么这有任何相关性。

这个问题一直是brought up on SO,但答案并不令人满意。它说“允许在对象被垃圾收集之前执行清理”,这甚至可能符合做出该设计决策的人的心态,但由于清理代码无法访问对象,因此它是否在之前执行或执行无关紧要对象被回收后。如上所述,由于此规则取决于 PhantomReference 对象的可达性,该对象需要优化代码转换,甚至可能会在清理代码完成之前将对象与 PhantomReference 实例一起回收,没有人注意到。

我在 2013 年还发现了一个 similar question on the HotSpot developer mailing list,它也没有答案。

有一个增强请求 JDK-8071507 来改变这种行为并清除 PhantomReferences 就像其他的一样,它对于 Java 9 的状态是“固定的”,事实上,javadocs 现在声明他们像任何其他参考一样被清除。”


总结:

  • 最初的设计决定不清除参考是有问题的。
  • 从 Java 9 开始,行为发生了变化。

但是你这样问你的问题:

那么为什么 JVM 等待手动 clear()

严格来说,JVM 等待要么 手动清除, 等待PhantomReference 本身变得无法访问。 (正如霍尔格上面所说的。)

所以它并不像您的问题所暗示的那么糟糕(在 Java 8 和更早版本中)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多