Я немного смущен использованием фантомных ссылок. Я читал, что когда Object, который имеет только ссылку Phantom, указывающую их, можно собирать всякий раз, когда коллекционеру мусора нравится это. Но в моем примере это не работает должным образом.Ссылка на фантом не освобождена во время GC
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 ClassTest {
private static Thread m_collector;
private static boolean m_stopped = false;
private static final ReferenceQueue refque = new ReferenceQueue();
Map<Reference,String> cleanUpMap = new HashMap<Reference,String>();
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() {
System.out.println("Creating phantom references");
class Referred {
}
Referred strong = new Referred();
PhantomReference<Referred> pref = new PhantomReference(strong, refque);
// cleanUpMap.put(pref, "Free up resources");
strong = null;
}
public static void collect() throws InterruptedException {
System.out.println("GC called");
System.gc();
System.out.println("Sleeping");
Thread.sleep(5000);
}
public static void main(String args[]) throws InterruptedException {
ClassTest test= new ClassTest();
test.startThread();
test.register();
test.collect();
m_stopped = true;
System.out.println("Done");
}
}
В приведенном выше примере, когда я запускаю, я вижу, что объект «сильный» не является мусором, собираемым автоматически. Я ожидал, что объект получит сбор мусора автоматически, когда «сильному» объекту присваивается значение null. Как ни странно, это сбор мусора, только когда я раскомментирую следующую строку в функции register.
//cleanUpMap.put(pref, "Free up resources");"
В чем причина этого? Но, если я создаю фантомную ссылку в самой главной функции, эта проблема не возникает. Другими словами, объект - это сбор мусора автоматически, когда «сильный» присваивается null внутри основной функции, как в следующем коде.
public static void main(String args[]) throws InterruptedException {
System.out.println("Creating phantom references");
// The reference itself will be appended to the dead queue for clean up.
ReferenceQueue dead = new ReferenceQueue();
PhantomReference<Referred> phantom = new PhantomReference(strong, dead);
strong = null;
// The object may now be collected
System.out.println("Suggesting collection");
System.gc();
System.out.println("Sleeping");
Thread.sleep(5000);
// Check for
Reference reference = dead.poll();
if (reference != null) {
System.out.println("not null");
}
System.out.println("Done");
}
Почему поведение отличается от обоих сценариев?
Возможный дубликат [Нужно ли поддерживать сильную ссылку на WeakReference, который используется только для выполнения финализации?] (Http://stackoverflow.com/questions/32108427/do-i-need-to-keep- a-strong-reference-to-a-weakreference-that-is-only-used-to-per) – the8472