【问题标题】:Why we are obliged to clear a PhantomReference manually?为什么我们必须手动清除 PhantomReference?
【发布时间】:2019-08-10 04:07:30
【问题描述】:
来自javadoc:
与软引用和弱引用不同,幻像引用在排队时不会被垃圾收集器自动清除。可以通过幻像引用访问的对象将保持不变,直到所有此类引用都被清除或自身变得不可访问。
一旦放入 ReferenceQueue,幻象链接的引用对象就被认为是“死的”,程序员的代码无论如何都无法访问它。那么为什么 JVM 等待手动 clear() 呢?对于弱参考,它不会。
【问题讨论】:
标签:
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 和更早版本中)。