クラス内のフィールドに参照対象がある場合、疑似参照に問題があります。クラスオブジェクトがnullに設定されている場合、フィールドは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:私は、参照キューにオブジェクトを登録したときに、それを印刷しCollectorを持っています収集されます。
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"フィールドは収集されないことがわかります。言い換えれば、「強い」がヌルに設定されている場合、「次の」は収集されません。私は、 "強い"がnullに設定されているときには、 "次へ"はもう参照されないので、GCによって自動的に "次へ"が収集されると仮定しました。しかし、 "strong.next"がnullに設定されていると、私たちが考えるように "next"が集められます。 strongがnullに設定されていると、「次へ」が自動的に収集されないのはなぜですか?
ありがとう、@holger。 – GoT