【问题标题】:Java PhantomReference is not getting enquedJava PhantomReference 未加入队列
【发布时间】:2014-10-02 12:42:08
【问题描述】:

我试图了解 PhantomReferences 在 Java 中的工作原理,并为此编写了这个程序。

public static void main(String[] args) throws InterruptedException {

    final ReferenceQueue refQueue = new ReferenceQueue();
    Employer emp = new Employer();
    emp.setName("John");
    PhantomReference<Employer> phantom = new PhantomReference<Employer>(emp, refQueue);
    List referenceList = new ArrayList();
    referenceList.add(phantom);

    Thread th = new Thread(new Runnable(){

        @Override
        public void run() {
            try {
                PhantomReference ref =  (PhantomReference) refQueue.remove();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }                        
        }                
    });
    th.start();

    for (int i = 0; i < 50000000; i++) {                
        if(i==(50000000-1)){
            Thread.sleep(10000);
            System.out.println(i);
            System.out.println("setting emp to null ");
            emp=null;
            System.gc();
        }                
    } 
}

但在这里,我没有看到 java API 文档中提到的引用被排入队列。 我在这里遗漏了什么吗?

【问题讨论】:

  • 1.您应该在此处发布代码。 2. 代码对我来说没有多大意义。你有一个空循环,然后是 Thread.sleep,然后是空引用,然后是 GC,然后立即退出。其他线程将没有时间得到通知。
  • 由于 refQueue.remove() 是一个阻塞调用,因此程序在入队之前永远不会退出。
  • 这很好;尝试简单地添加 两个 System.gc() 调用,看看会发生什么。
  • 我什至尝试过使用详细的 GC,我看到在将引用设置为 null 后触发了 GC,但它没有进入队列。
  • 没关系,GC 运行有很多问题,并不是所有问题都发生在同一次运行中。您必须意识到您正在探究一种特定 JVM 实现的未指定行为。

标签: java reference garbage-collection


【解决方案1】:

这是重复的……但我找不到原件。

简而言之:它被排入队列......总有一天。不是马上。也许在下一次 GC 运行之后,也许是下周。无法保证时间。

【讨论】:

  • +1 而且,如果所有其他线程都死了,那么如果不是马上就不会发生。
猜你喜欢
  • 2017-05-14
  • 1970-01-01
  • 2013-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多