我遇到幻像参考时出现问题,当参照物是类内部的字段时。当类对象被设置为空,字段不会自动通过GC一个类的内部字段不由GC通过幻像参考收集
Controller.java
public class Controller {
public static void main(String[] args) throws InterruptedException
{
Collector test = new Collector();
test.startThread();
Reffered strong = new Reffered();
strong.register();
strong = null; //It doesn't work
//strong.next =null; //It works
test.collect();
Collector.m_stopped = true;
System.out.println("Done");
}
}
Collector.java收集:我有,其登记一个目的是参考队列并打印出来,当它收集器被收集。
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.HashMap;
import java.util.Map;
public class Collector {
private static Thread m_collector;
public static boolean m_stopped = false;
private static final ReferenceQueue refque = new ReferenceQueue();
Map<Reference,String> cleanUpMap = new HashMap<Reference,String>();
PhantomReference<Reffered> pref;
public void startThread() {
m_collector = new Thread() {
public void run() {
while (!m_stopped) {
try {
Reference ref = refque.remove(1000);
System.out.println(" Timeout ");
if (null != ref) {
System.out.println(" ref not null ");
}
} catch (Exception ex) {
break;
}
}
}
};
m_collector.setDaemon(true);
m_collector.start();
}
public void register(Test obj) {
System.out.println("Creating phantom references");
//Referred strong = new Referred();
pref = new PhantomReference(obj, refque);
cleanUpMap.put(pref, "Free up resources");
}
public static void collect() throws InterruptedException {
System.out.println("GC called");
System.gc();
System.out.println("Sleeping");
Thread.sleep(5000);
}
}
Reffered.java
public class Reffered {
int i;
public Collector test;
public Test next;
Reffered() {
test= new Collector();
next = new Test();
}
void register() {
test.register(next);
}
}
测试是一个空类。当Reffered对象设置为null时,我可以看到Refferred类中的“next”字段未被收集。换句话说,当“强”被设置为空时,“下一个”不被收集。我认为GC将自动收集“下一个”,因为当“strong”设置为空时“next”不再被引用。但是,当“strong.next”设置为空时,我们认为收集“下一个”。为什么当strong被设置为null时不会自动收集“next”?
谢谢,@holger。 – GoT