【问题标题】:Java Garbage collection, setting reference to nullJava垃圾收集,设置引用为null
【发布时间】:2012-03-17 04:53:01
【问题描述】:
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 条件吗?
【问题讨论】:
标签:
java
garbage-collection
【解决方案1】:
您创建的对obj2 的唯一引用位于obj1 (b.a = new A();) 内。一旦你失去了对obj1 (b = null;) 的引用,你也失去了对obj2 的引用,所以是的,它有资格获得 GC。
【解决方案2】:
如果您想确定一个对象是否适合进行垃圾回收,请尝试查看它是否可以从根集访问。根集是从调用堆栈和全局变量中引用的对象之类的东西。
在您的示例中,根集最初由 obj1 和 args 组成(让我们忽略可能存在的任何其他 - 它们对您的示例无关紧要)。就在第 6 行之前,obj2 显然可以从根集到达,因为obj1 包含对obj2 的引用。但是在第 7 行之后,根集中的唯一对象是 args。 obj1 或 obj2 不可能从 args 引用,因此在第 8 行,obj1 和 obj2 都符合收集条件。
【解决方案3】:
是的,这是一个展示 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
【解决方案4】:
b = null;
没用,因为在一行之后你已经到达 b 范围的末尾。离开定义它们的范围后,这两个对象都无法访问,因为它们的引用没有通过方法调用或作为构造函数调用中的参数放置在其他地方,或者作为来自其他地方的反向引用,已在其他地方发布.