【发布时间】: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