4

我的问题,总结了这一切:PhantomReference能否通过内存回收来停止其引用?

  • 可强可到达的Java幻影从由垃圾收集器(GC)被回收停止其所指对象的内存?

详细情况如下:

Callum posted this question以及但是它不是直截了当地回答。有一个回应指的是Ethan Nicholas的一篇文章,这篇文章似乎用“不”来回答我的问题,但我不确定这是否正确。

根据我的Java API的我会回答我“是”问题阅读:

  • 只要PhantomReference.clear()不叫,和幻影实例本身仍然有着强烈的指的是,所指对象的内存将永远不会被回收,并且所指对象将保持在虚幻可达状态。

为了支持这样的认识,我会引用Java Docs

  • “不像软,弱引用,虚引用是,因为他们排队不会自动垃圾收集清理的对象,可以通过幻影访问,直到所有这些引用都被清除或者自己变得无法访问。“

例如,假设我做了一个幻影参考并将该实例保存在PhantomReference的List中。然后它的指称从可达到幻像可达。

如果你看一看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

您是否考虑过简单地测试它?调试器,反射或heapdump可以在GC之后查看引用。或者你可以通过抓住非常大的物体来强制一个OOME。 – the8472

回答

2

你混淆了两件事。链接的问题不是关于指称对象,而是PhantomReference实例。与所有引用对象一样,PhantomReference实例可以像其他任何对象一样被垃圾收集,只要它没有被入队。这在package specification中指定:

注册的引用对象与其队列之间的关系是单向的。也就是说,一个队列不跟踪注册的引用。如果注册的引用本身变得无法访问,那么它永远不会入队。程序使用引用对象负责确保只要程序对其对象感兴趣,对象就可以保持可达状态。

但是你的问题是关于指代物。另外,引用的代码是关于处理已经排队并且甚至从队列中检索的引用。

在这个地方,你引用的文档适用。直到并包括Java 8,可到达PhantomReference的对象不会被自动清除,因此所指对象保持幻像可达,直到该对象被清除或变得本身无法访问为止。因此,引用的代码在清除引用时是正确的,以允许提前回收,但差异仅影响清除方法执行的持续时间,因为之后的PhantomReference可能本身无法访问。


但这不是故事的结尾。没有明确的理由,为什么对象应该保持幽灵可达,而不是被回收。毕竟,清理方法无论如何都无法访问指示对象。

因此Java 9会删除该规则,并像其他引用一样自动清除幻像引用。因此,从Java 9开始,手动清除已经排入队列的幻影引用是不必要的,但当然不会造成伤害,所以旧软件仍然可以顺利运行。


关于您例如:

...让我们说我做一个虚引用,并保持该实例在幻影的名单。然后它的指称从可达到幻像可达。

作为仅参考PhantomReference参考的指称是不足以幻像可及。它还要求没有强引用,并且对象已经完成,但对于大多数对象而言,实际上跳过了最终确定,因为它们没有自定义的finalize()方法。除了幻像参考还有软引用时,它可能取决于配置和内存需求,引用是否会变成虚幻可及。

+0

至少我可以做的是在这里注册,我只读过这个,从来没有用过,但看起来你已经完成了这个! – Eugene

+0

@Eugene:我也没有在应用程序代码中使用它。在非常罕见的情况下,我会使用'WeakReference'来避免“未自动清除”问题的性能含义。由于我们从来没有不小的'finalize()'方法,所以这些参考类型与我们没有区别。我熟悉这个的原因是,自从发布jdk1.2以来,我一直在唠叨我,但我并没有完全理解它。尽管文档还有改进的空间,但Java 9回答了我最后一个问题,为什么他们没有被清除。 – Holger

+0

我同意@Eugene--我现在还没有深入到这些领域,并且不打算这么做,所以我无法验证任何陈述。你似乎在这个问题上。将您的帖子标记为答案。谢谢@Holger! :-) –

相关问题