gpt4 book ai didi

java - PhantomReference 能否阻止其引用对象进行内存回收?

转载 作者:搜寻专家 更新时间:2023-11-01 03:21:04 25 4
gpt4 key购买 nike

我的问题总结了这一切:

  • 强可达 Java PhantomReference 能否阻止其引用对象的内存被垃圾收集器 (GC) 回收?

详情如下:

Callum posted this question也是,但没有直接回答。那里的一个回复提到了 Ethan Nicholas 的一篇文章这似乎用“否”回答了我的问题,但我不确定这是正确的。

根据我对 Java API 的阅读,我必须用"is"来回答我的问题:

  • 只要不调用 PhantomReference.clear(),并且 PhantomReference 实例本身仍然被强烈引用,引用对象的内存将永远不会被回收,引用对象将保持在幻象可达状态。

为了支持这种理解,我将引用 Java Docs :

  • “与软引用和弱引用不同,幻影引用在入队时不会自动清除通过幻影引用可访问的对象将一直保持到所有此类引用为止被清除或它们自己变得无法访问。”

例如,假设我创建了一个虚引用并将该实例保存在虚引用列表中。然后它的指示对象从强可达变为幻可达。

如果您查看 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();      ...  }

我更希望由对该主题有经验的人来回答,而不是进行网络搜索并向我提供链接。谢谢!

最佳答案

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

The relationship between a registered reference object and its queue is one-sided. That is, a queue does not keep track of the references that are registered with it. If a registered reference becomes unreachable itself, then it will never be enqueued. It is the responsibility of the program using reference objects to ensure that the objects remain reachable for as long as the program is interested in their referents.

但是你的问题是关于所指的。此外,引用的代码是关于处理已经入队甚至从队列中检索的引用。

在此处,您引用的文档适用。直到并包括 Java 8,可访问的 PhantomReference 的引用不会被自动清除,因此引用保持幻象可达,直到引用被清除或自身变得不可访问。因此,引用的代码在明确清除引用以允许早期回收方面是正确的,但差异仅影响清理方法执行的持续时间,因为之后,PhantomReference 本身可能变得无法访问。


但这并不是故事的结局。没有明确的理由说明为什么 referents 应该保持 phantom reachable 而不是被回收。毕竟,cleanup 方法无法访问 referent。

因此 Java 9 放弃了该规则并像任何其他引用一样自动清除幻像引用。所以从 Java 9 开始,手动清除已经入队的幻象引用是不必要的,当然,也没有坏处,所以旧软件仍然可以顺利运行。


关于你的例子:

…let's say I make a phantom reference and keep that instance in a List of PhantomReference. Then its referent falls from strongly reachable to phantom reachable.

仅作为 PhantomReference 引用的引用不足以实现幻象可达。它还要求没有强引用并且对象已经完成,尽管大多数对象实际上跳过了完成,因为它们没有自定义 finalize() 方法。当除了幻象引用之外还有软引用时,可能取决于配置和内存需求,引用对象是否变为幻象可达。

关于java - PhantomReference 能否阻止其引用对象进行内存回收?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30500316/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com