我的问题总结了一切:
详细信息如下:
Callum posted this question但也没有直截了当地回答。其中一个回复是Ethan Nicholas的一篇文章,似乎用一个" No"来回答我的问题。但我不确定这是否正确。
基于我对Java API的阅读,我必须回答我的问题"是":
为了支持这种理解,我将引用Java Docs:
例如,让我说我做了一个幻像引用并将该实例保存在PhantomReference列表中。然后它的指示物从强烈可达到幻象可达。
如果你看一下com.google.common.base.internal.Finalizer.java,你会看到以下代码:
private void cleanUp(Reference reference) throws ShutDown { ... /* * This is for the benefit of phantom references. Weak and soft * references will have already been cleared by this point. */ reference.clear(); ... }
我希望有这个主题经验的人能够做出回应而不是进行网络搜索并向我提供链接。谢谢!
答案 0 :(得分:2)
你混淆了两件事。链接的问题不是指示对象,而是PhantomReference
实例。与所有引用对象一样,PhantomReference
实例可以像任何其他对象一样收集垃圾,只要它没有排队。这在package specification:
注册参考对象与其队列之间的关系是片面的。也就是说,队列不会跟踪向其注册的引用。如果注册的引用本身无法访问,那么它将永远不会被入队。使用引用对象的程序负责确保只要程序对其所指对象感兴趣,对象就可以保持可达。
但你的问题是关于指称。此外,引用的代码是关于处理已经入队甚至从队列中检索的引用。
在这个地方,您引用的文档适用。直到并包括Java 8,可访问的PhantomReference
的引用不会自动清除,因此引用保持幻像可达,直到引用被清除或自身无法访问。因此,引用的代码在明确清除引用以允许早期回收时是正确的,但差异仅影响清理方法执行的持续时间,因为之后PhantomReference
可能变得无法访问。
但这不是故事的结局。没有明确的理由说明参考物应该保持幻影可达而不是被收回。毕竟,无论如何,清理方法都无法访问指示对象。
因此,Java 9会删除该规则,并像其他任何引用一样自动清除幻像引用。因此,从Java 9开始,手动清除已经排队的幻像引用是不必要的,但当然不会受到影响,因此旧软件仍然可以顺利运行。
关于你的例子:
...让我说我做了一个幻像引用并将该实例保存在PhantomReference列表中。然后它的指示物从强烈可达到幻象可达。
单独作为PhantomReference
引用的引用并不足以使幻像可达。它还要求没有强引用并且对象已经完成,尽管对于大多数对象实际上跳过了最终化,因为它们没有自定义finalize()
方法。当幻像引用附加软引用时,它可能取决于配置和内存需求,引用是否会变为幻像可达。