javagarbage-collectionocpjp

Eligible variables for garbage collection in Java


I am preparing for OCPJP, and I got stuck at the following mock exam question:

Given:

3. interface Animal { void makeNoise(); }

4. class Horse implements Animal {
5.     Long weight = 1200L;
6.     public void makeNoise() { System.out.println("whinny"); }
7. }

8. public class Icelandic extends Horse {
9.     public void makeNoise() { System.out.println("vinny"); }

10.    public static void main(String[] args) {
11.        Icelandic i1 = new Icelandic();
12.        Icelandic i2 = new Icelandic();
12.        Icelandic i3 = new Icelandic();
13.        i3 = i1; i1 = i2; i2 = null; i3 = i1;
14.    }
15. }

When line 14 is reached, how many objects are eligible for the garbage collector?

A. 0

B. 1

C. 2

D. 3

E. 4

F. 6

Their correct answer is E, i.e. four objects, but I'm not sure why. From my point of view, i2 and its weight will get eligible for garbage collection. Perhaps I'm missing something, please advise.


Solution

  • Lets call Icelandic() on line 11 IceA, line 12 IceB, and so forth.

    After creation

    i1 = IceA
    i2 = IceB
    i3 = IceC
    

    After i3 = i1

    i1 = IceA
    i2 = IceB
    i3 = IceA
    

    After i1 = i2

    i1 = IceB
    i2 = IceB
    i3 = IceA
    

    After i2 = null

    i1 = IceB
    i2 = null
    i3 = IceA
    

    After i3 = i1

    i1 = IceB
    i2 = null
    i3 = IceB
    

    So only the Icelandic() created on line 12 remains. Now, each Icelandic() has a Long weight, so IceA and IceC are now unreferenced, meaning 4 objects (IceA, IceA.weight, IceC, IceC.weight) are available for GC.


    Other issues:

    1. args is still args, they are not counting going out of scope in this question
    2. Long weight is not declared statically, so each instance of the class has a weight object.