public class A{
A a;
public static void main(String args[]){
A b = new A();//new object created, obj1
b.a = new A();//new object created, obj2
b = null;
//line 8
}
}
当达到第8行时,obj1符合GC的条件。 obj2是否也有资格获得GC?
答案 0 :(得分:5)
您为obj2
创建的唯一引用位于obj1
(b.a = new A();
)内。一旦您丢失了对obj1
(b = null;
)的引用,您也会丢失对obj2
的引用,所以是的,它符合GC的条件。
答案 1 :(得分:3)
如果您想确定对象是否符合垃圾回收的要求,请尝试查看是否可以从根集中访问它。根集类似于从调用堆栈和全局变量引用的对象。
在您的示例中,根集最初包括obj1
和args
(让我们忽略可能存在的任何其他内容 - 它们对您的示例无关紧要)。在第6行之前,obj2
可以从根集清楚地到达,因为obj1
包含对obj2
的引用。但是在第7行之后,根集中唯一的对象是args
。 obj1
或obj2
无法引用args
或obj1
,因此在第8行,obj2
和{{1}}都有资格收集。
答案 2 :(得分:1)
是的,这是一个显示GC实际运作的例子:
static int c = 2;
public static void main(String args[]) throws Exception {
class A{
A a;
}
A b = new A(){
public void finalize(){
System.out.println("obj 1 has been GC'd");
c--;
}
};
b.a = new A(){
public void finalize(){
System.out.println("obj 2 has been GC'd");
c--;
}
};
b = null;
while(c>0) {
System.gc();
Thread.sleep(42);
}
}
输出:
obj 1 has been GC'd
obj 2 has been GC'd
答案 3 :(得分:0)
b = null;
没用,因为一行之后你已经到了b的范围的末尾。离开定义它们的范围之后,2个对象都不可到达,因为它们的引用不是放在其他地方,通过方法调用或构造函数调用中的参数,或者作为其他地方的反向引用,这是在其他地方发布的。