我正在研究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)?
答案 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对象不再可达。