【问题标题】:What is the relationship between the PhantomReference and ReferenceQueue?PhantomReference 和 ReferenceQueue 是什么关系?
【发布时间】:2014-10-08 15:37:43
【问题描述】:

我对 java 中的 PhantomReference 有点困惑。当我查看在线文章时,他们中的大多数都提到 PhantomReference 对象在创建后将返回 null 即使我们在引用上调用 get() 并且它还提到当 PhantomReference 被删除时,对象是幻影可访问的将被插入到 ReferenceQueue 中记忆。

我已经尝试了以下代码示例,但我对结果感到困惑。

Equipment equipment = new Equipment();  
ReferenceQueue queue = new ReferenceQueue();  
PhantomReference pr = new PhantomReference(equipment, queue);

System.out.println(pr.get());  
System.out.println(queue.poll()); 

以上两个语句打印 null。如果 pr.get() 返回 null 是否意味着 pr 引用的对象被垃圾收集? 如果是,为什么对象还没有加入优先队列?

谁能帮我澄清一下。如果我对 PhantomReference 和 ReferenceQueue 的理解有误,我向您道歉。

请简单描述这两个术语

非常感谢

【问题讨论】:

    标签: java phantom-reference


    【解决方案1】:

    PhantomReference#get() always returns null

    返回此引用对象的所指对象。因为一个参照物 幻象引用总是不可访问的,这个方法总是返回 空。

    你无法通过get()知道它是否被收集。

    如果是,为什么对象还没有加入到优先队列中

    javadoc 状态

    如果垃圾收集器在某个时间点确定 幻影引用的所指对象是幻影可达的,然后在那 某个时间或稍后的某个时间它会将引用排入队列。

    因此,要么在调用 poll()(非阻塞)时实例尚未被垃圾回收,要么实例已被垃圾回收,但对应的 PhantomReference 未添加到 ReferenceQueue

    您可以通过将强引用设置为 null 并请求 GC 来帮助它,但也可以阻止队列中的 remove Reference

    equipment = null;
    System.out.println(pr.get());
    System.gc();
    System.out.println(queue.remove()); // block and wait for it to be added
    

    【讨论】:

    • 感谢您的回答,它帮助我更清楚地理解上下文,但我想知道您为什么调用 System.gc();然后调用 queue.remove()。你能解释一下吗
    • @user3115189 System.gc() 是对垃圾收集器的建议,可以垃圾收集任何可能的东西。它让我们有更好的机会看到Equipment 对象被垃圾回收。调用 queue.remove() 而不是 poll() 因为它会阻塞等待队列中可用的条目。请参阅我的回答中来自 javadoc 的引用。可以在稍后将幻像引用添加到队列中。我们希望等到这种情况发生。
    猜你喜欢
    • 2013-07-24
    • 2014-03-14
    • 2013-06-14
    • 2018-02-16
    • 2020-05-04
    • 2020-01-08
    • 2015-01-13
    • 2017-11-06
    • 2015-07-09
    相关资源
    最近更新 更多