PhantomReference不可达时的行为?代码场景下的入队疑问
问题:当PhantomReference对象自身变为不可达时,会发生什么?
请考虑以下代码:
public static final ReferenceQueue<Object> REF_QUEUE = new ReferenceQueue<>(); public class Foo extends PhantomReference<Object> { public Foo(Object obj) { super(obj, REF_QUEUE); } } public class Bar { private Foo foo; public void refTest() { foo = new Foo(new Apple("Cortland")); foo = null; } }
PhantomReference的文档说明如下:
If the garbage collector determines at a certain point in time that the referent of a phantom reference is phantom reachable, then at that time or at some later time it will enqueue the reference.
在refTest方法中,由于持有Cortland Apple的Foo对象变为不可达,该Apple对象也随之变为不可达(而非phantom reachable)。请问此时Foo对象会被加入REF_QUEUE队列吗?
回答
不会。
原因如下:
- PhantomReference的入队逻辑仅在其referent(即被引用的对象,这里是Apple实例)处于虚可达(phantom reachable)状态时才会触发。而虚可达的前提是:被引用对象没有强、软、弱引用指向它,但存在至少一个可达的PhantomReference指向它。
- 在代码的
refTest方法中,当执行foo = null后,Foo实例(也就是这个PhantomReference对象)本身已经没有任何存活的引用,直接变为不可达。此时它的referent(Apple对象)也失去了所有存活的引用——连原本指向它的PhantomReference都已经不可达了,所以Apple对象直接进入“完全不可达”状态,而非“虚可达”状态。 - 由于不满足文档中描述的入队触发条件,这个Foo对象不会被加入REF_QUEUE,最终会和Apple对象一起被垃圾回收器回收。
内容的提问来源于stack exchange,提问作者G. Blake Meike
相关产品推荐
相关产品推荐

