对象是否符合GC的条件,即使其实例变量是对另一个变量的引用?

时间:2016-09-13 14:21:15

标签: java garbage-collection

我正在研究Java认证1Z0-803,我对垃圾收集存在疑问:

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引用在位置1创建的对象X 此类X具有类型List的实例变量。
如果我在局部变量list中的X类型的x上引用了实例变量list,然后将x设置为null,则为x引用的对象在这一行(第2位)有资格获得GC,或者因为我引用了这个对象的实例变量,当它的实例变量没有任何引用时,该对象只适用于GC(位置3)?

3 个答案:

答案 0 :(得分:6)

最初,你有

stack --> x --> list
因此,x可以从堆栈中到达。

然后你有

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

x仍然可以从堆栈中访问,并且列表也可以通过x和堆栈上的局部变量到达

然后你将x设置为null,所以你有

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

你因此看到现在有办法从堆栈中到达x。存在从x到列表的路径的事实是无关紧要的。因此允许VM收集x:

 stack           list
     \          /
      \--------/

答案 1 :(得分:2)

它将在2.您没有引用x的变量,您正在引用List。 x也具有对List的引用这一事实不会影响其对垃圾收集的资格。 List不是“inside”x,只是对List的引用。

当然,List本身不符合垃圾收集的条件,因为它仍然在main中引用,但List和x是独立的对象。

答案 2 :(得分:1)

位置2,因为此时X对象不再可达。