Here is my code
public class FinalizableObject {
@Override
protected void finalize() throws Throwable {
System.out.println("finalize() invoked for " + this);
super.finalize();
}
}
public class Main {
private static void test() throws InterruptedException {
ReferenceQueue<FinalizableObject> rq = new ReferenceQueue<FinalizableObject>();
FinalizableObject obj = new FinalizableObject();
PhantomReference<FinalizableObject> pr1 = new PhantomReference<FinalizableObject>(obj, rq);
obj = null;
System.gc();
Reference<? extends Object> ref = rq.remove();
System.out.print("remove " + ref + " from reference queue\n");
}
public static void main(String[] args) {
try {
test();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
It's very strange, rq.remove() will be blocked forever. Why my finalizable object's phantom reference can not be put into reference queue? Has it been GC collected?
I know the FinalizerReferenceQueue and FinalizerDeamon, 2 times of GC can fully collect an finalizable object. But I can not understand why 100 times of GC will trigger it to be collected (even 20 times of GC can not trigger the enqueue).
On the other hand, if I replace the PhantomReference by WeakReference, it can remove the reference very quickly.
– Devboard Fan Jul 25 '13 at 07:45