How many objects will be eligible for garbage collection after executing "m1=null; m2=null;"?
Solution 1:
Zero.
Object reference diagram looks like this:
You can see that the reference is circular. A reference from main
to m3
keeps the m3
object alive. In turn, m3
keeps alive m1
, which keeps m2
from GC.
Note that if you set m3
to null
, all three objects would become eligible for GC at once, despite circular references existing for each one of them. GC is smart enough to figure out that all references are coming from GC-eligible objects, and collect all three.
Solution 2:
Potentially all 3 of them. No variables are referenced after the //
marker, so the optimizer is within its rights to drop them off the frame at this point.
Solution 3:
Voila! GC will collect nothing here! Let's see what actually is going on here. When you created three objects of m1
, m2
and m3
of MyTest
, the object was created like below (say the object reference id starts from 410):
m1 MyTest (id=410)
m null
m2 MyTest (id=412)
m null
m3 MyTest (id=414)
m null
When you initialize
m1.m = m2;
m2.m = m3;
m3.m = m1;
The objects are now looks like:
m1 MyTest (id=410)
m MyTest (id=412)
m2 MyTest (id=412)
m MyTest (id=414)
m3 MyTest (id=414)
m MyTest (id=410)
m MyTest (id=412)
m MyTest (id=414)
m MyTest (id=410)
.
.
. (This is circular)
But after you reinitialized m1
and m2
to null
, the objects look like:
m1 null
m2 null
m3 MyTest (id=414)
m MyTest (id=410)
m MyTest (id=412)
m MyTest (id=414)
m MyTest (id=410)
.
.
.
Look, m1
and m2
are null
now, but their references are still alive in m3
!
Solution 4:
None as they are still all reachable through the circular reference you build there through m3