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:
- Java: PhantomReference, ReferenceQueue and finalize
- Discovering Objects with Non-trivial Finalizers
- The Secret Life Of The Finalizer: page 2 of 2
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();