6

I'm studing for the Java Certification 1Z0-803 and I hava a doubt about garbage collection:

import java.util.*;

class X {
    List<String> list = new ArrayList<>();
}

public class TestGC {
    // Is an Object eligible for GC even if its instance variable is references to another variable
    public static void main(String[] args){
        X x = new X(); // 1
        List<String> list = x.list;
        x = null; // 2, Is X object reference eligible for garbage collection here?

        list.add("a");
        list.add("b");
        list.add("c");

        for(String item : list) {
            System.out.println(item);
        }
        list = null;// 3, Or X object reference eligible for garbage collection here, after list is set to null
    }
}

x is referencing the object X created at the position 1.
This class X has a instance variable of the type List.
If I referenced the instance variable list on x of the type X in a local variable list and then set x to null, the object referenced for x will be eligible for GC in this line (position 2) or because I'm referencing an instance variable of this object, this object only be eligible for GC when its instance variable does not have anything reference to it (position 3)?

Erick Alves
  • 354
  • 1
  • 4
  • 10
  • Just a side note: at point 3, the `ArrayList` is eligible for garbage collection, even if you don’t set `list` to `null`, as the variable’s scope ends there. But even if the variable had a larger scope, the fact that it is never read afterwards, makes the object unreachable. If you are interested in this subtle aspect, read [“finalize() called on strongly reachable object…”](http://stackoverflow.com/q/26642153/2711488). Since your code actually does nothing, an optimizing execution environment could collect the objects even earlier or not create them in the first place. – Holger Sep 14 '16 at 14:49

3 Answers3

7

Initially, you have

stack --> x --> list

x is thus reachable from the stack.

Then you have

stack --> x --> list
     \          /
      \--------/

x is still reachable from the stack, and list is reachable, too, through x, and through the local variable on the stack

Then you set x to null, so you have

 stack      x --> list
     \          /
      \--------/

And you thus see that there is now way to reach x anymore from the stack. The fact that there is a path from x to the list is irrelevant. So the VM is allowed to collect x:

 stack           list
     \          /
      \--------/
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
2

It will be at 2. You aren't referencing the variable of x, you are referencing the List. The fact that x also has a reference to the List does not affect its eligibility for garbage collection. The List is not "inside" x, only a reference to the List is.

The List itself, of course, is not eligible for garbage collection because it is still referenced in the main, but the List and x are independent objects.

puhlen
  • 8,400
  • 1
  • 16
  • 31
1

Position 2, because at this point the X object is no longer reachable.

Welbog
  • 59,154
  • 9
  • 110
  • 123