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?
The problem is with your non-trivial finalize()
method. In default implementation (in class Object
) this method is actually empty. When its implementation isn't empty, then it is not guaranteed that object will be instantly collected after invoking finalize()
.
If you will modify your program in such style:
for (int i = 0; i < 1000; i++)
System.gc();
i.e. you will call GC more then one times - it could lead to the rq
object be fully collected (test on my machine).
Also, I suggest you following links to explore:
UPD: Another way: you have to hold in mind, that non-trivial finalize()
methods is invoked by special Finalizer-Thread, which also have to be collected. So, for full pr
collecting you can do such things:
a) create flag inside Main
method:
public static volatile boolean flag;
b) set flag in finalize()
method:
@Override
protected void finalize() throws Throwable {
System.out.println("finalize() invoked for " + this);
super.finalize();
Main.flag = true;
}
c) check flag for true and then call gc()
again:
System.gc();
while (!flag) Thread.sleep(10);
System.gc();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With