The garbage collection in last versions of JVM follows optimized principles to decide if a object is out of scope in a executed program.
It is rarely limited to the scope of the method.
From Oracle documentation :
What is Automatic Garbage Collection?
Automatic garbage collection is the process of looking at heap memory,
identifying which objects are in use and which are not, and deleting
the unused objects. An in use object, or a referenced object, means
that some part of your program still maintains a pointer to that
object. An unused object, or unreferenced object, is no longer
referenced by any part of your program. So the memory used by an
unreferenced object can be reclaimed.
The two last sentences matters :
An unused object, or unreferenced object, is no longer referenced by any part of your program. So the memory used by an unreferenced object can be reclaimed.
In your sample code :
public static void main(String[] args) {
A a = new A();
System.out.println("Main thread created object " + a);
for (int i = 0; i < 1000000000; i++) {
if (i % 100000000 == 0)
System.gc();
}
}
when System.gc();
is invoked, a
is no longer referenced by any part of your program so a garbage collect request may mark it to be freed.
Now when you add System.out.println(a + "is residing on heap and is alive");
} , it may make sense that the finalizer is never called.
It is not called when gc() is invoked as it is still referenced latter but the sysout is also the last line of the program.
The a
instance is a instance of the main thread class (A
).
If the main thread is finished, the current JVM process is down.
In these conditions, the finalize()
method of it has probably no way to be executed.
Ps : sorry for multiple edits. I am on my phone...