gpt4 book ai didi

java - 将 PhantomReference 指向 `this` 是否安全?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:59:55 24 4
gpt4 key购买 nike

我有一个共享资源,我想知道有多少其他对象仍在使用该资源。为此,我想使用 PhantomReference

由于 ReferenceQueue 不跟踪为它们注册的引用(source,“通知”部分),我的想法是将引用存储为被跟踪对象的字段:

class Foo {
private PhantomReference<Foo> thisReference;

public Foo(ReferenceQueue<Foo> queue) {
thisReference = new PhantomReference<>(this, queue);
}
}

这是否安全,基于 PhantomReference 的 Java 9(+) 行为,或者是否有可能在没有将引用添加到队列的情况下对实例进行垃圾回收?

文档说:

Suppose the garbage collector determines at a certain point in time that an object is phantom reachable. At that time it will atomically clear all phantom references to that object and all phantom references to any other phantom-reachable objects from which that object is reachable. At the same time or at some later time it will enqueue those newly-cleared phantom references that are registered with reference queues.

但是它没有提到是否可以在引用入队之前进行垃圾回收。

最佳答案

package documentation包含误导性的短语:“一个对象是幻影可达,如果它既不是强可达的,也不是弱可达的,它已经完成,并且有一些幻影引用指向它。”

“一些幻象引用”并没有强调引用对象本身必须是可达的这一事实,这在通知部分中有说明:

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.

由于幻象可达除了可能导致幻象引用排队外没有任何实际后果,这才是最重要的。

注意软可达性和弱可达性的定义比较好:

  • An object is softly reachable if it is not strongly reachable but can be reached by traversing a soft reference.
  • An object is weakly reachable if it is neither strongly nor softly reachable but can be reached by traversing a weak reference. …

这里强调对象必须通过引用对象可达,也就是说引用对象也必须是可达的。

以类似的方式定义幻影可达性的问题在于,幻影可达对象实际上是无法访问的,因为 PhantomReference 覆盖了 get() 方法以始终返回null,因此应用程序无法到达所指对象,因此不会遍历任何幻象可到达对象。

也许,一个更好的定义是

  • An object is phantom reachable if it is neither strongly, softly, nor weakly reachable, it has been finalized, but can be reached by the garbage collector by traversing a phantom reference.

根据该定义,很明显您的带有自引用的示例将不起作用,就像它不适用于 WeakReferenceSoftReference .请注意,当您的类没有专用的 finalize() 方法时,使用 WeakReferencePhantomReference 之间没有实际区别。

似乎连 API 设计者都没有完全理解其中的含义,因为 specification prior to Java 9包含规则:

Unlike soft and weak references, phantom references are not automatically cleared by the garbage collector as they are enqueued. An object that is reachable via phantom references will remain so until all such references are cleared or themselves become unreachable.

它公然忽略了一个幻影可达对象不可访问的观点,至少从应用程序的角度来看,并保持它幻影可达从垃圾收集器的角度来看没有实际好处。不让对象再次 Activity ,这就是最终确定的不同之处。但请注意,在此处,文档承认如果幻象引用本身变得不可访问,则所指对象将不再是幻象可达

从 Java 9 开始,幻影引用在入队时会自动清除,因此对象从幻影可达不可达的唯一实际影响是幻影引用被排队。这需要引用对象是可访问的。

关于java - 将 PhantomReference 指向 `this` 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56414473/

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