[英]why the following object is not eligible for garbage collection?
在下面的以下代码中,我不明白为什么使用引用b2
创建的对象不是null
。 正如我通过将b2 = null
传递给b1
的对象的go()
方法一样(在使b1 = null
)。
class Demo {
Short story = 200;
Demo go(Demo cb) {
cb = null;
return cb;
}
public static void main(String[] args) {
demo b1 = new demo();
demo b2 = new demo();
demo b3 = b1.go(b2);
b1 = null;
// b1 has been collected by gc hence is null
System.out.println(b1.hashCode());
// b3 is also null
System.out.println(b3.hashCode());
// but how come b2 is not null?
System.out.println(b2.hashCode());
}
}
因此,请有人向我解释为什么即使将b2设为null也不收集垃圾?
demo b3 = b1.go(b2);
Demo go(Demo cb){
cb = null;
return cb;
}
使用上面的代码,第一个b2
和cb
都将指向同一对象。 然后当你做cb = null;
然后cb
,引用丢失。 但是b2
仍然指向原始对象。
这意味着至少一个对象( b2
)正在主动保存对已分配内存/对象的引用。 它不符合垃圾收集的条件。
将任何对象设置为null
引用并不意味着它由垃圾收集器收集。 这只是意味着,现在没有对分配对象的活动引用,因此可以进行垃圾回收。
首先,您需要知道垃圾回收(GC)与将某些内容设置为null不同。
让我在这里做个比喻。 变量( b1
, b2
, b3
等)就像孩子。 对象( new Demo()
)就像气球。 当你写:
demo b1 = new demo();
您让孩子b1
抱着一个新气球。 当将b1
设置为null时,会让孩子放开气球。 气球飞走了,但它仍然存在于天空中的某个地方。 另一方面,GC就像是一台能够捕捉这些飞行气球的超级高科技机器。 孩子放开气球后,GC会在一段时间后注意到它(此“时间”可能会有所不同),然后去收集并销毁它。
既然您已经了解了无效和GC之间的区别,那么我们可以继续讨论您的实际问题。 在方法中
Demo go(Demo cb){
cb = null;
return cb;
}
您正在将cb设置为null并返回它。 返回值为空。 但是, cb
不是您先前传入的子级( b2
)。 您有一个正在拿着气球的孩子( b2
),并且当您“将孩子作为参数传递”时,您没有在传递孩子,而是邀请另一个孩子继续使用同一气球。 在该方法中, cb
是另一个孩子。 因此,当将cb
设置为null时,您放开了“另一个孩子”气球,但是原始孩子b2
仍然持有它。
看到? b2仍然拿着气球! 他不是空的!
因为cb指向与b2相同的对象,但是cb与b2不同。 将cb设置为null不会对b2或b2指向的对象产生任何影响。
那不是垃圾收集的工作方式。 垃圾收集器将找到不再有任何引用的对象,并进行收集。 它不会收集仍然有引用的对象,也不会将任何变量设置为null。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.