[英]Garbage Collection of Objects passed as arguments and being set to null in a method
我一直试图理解这个问题,但无法解决书中提供的答案。 有人可以向我解释一下吗? 问题如下。
class CardBoard {
Short story = 5;
CardBoard go(CardBoard cb) {
cb = null;
return cb;
}
public static void main(String[] args) {
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(c2);
c1 = null;
// do stuff
}
}
// 当达到 do stuff 时,有多少对象可以进行垃圾回收?
给出的答案是2 个对象。 只有一个 CardBoard 对象 (c1) 符合条件,但它有一个相关的 Short 包装对象也符合条件
我不明白为什么只有对象 c1 才有资格进行垃圾收集。
创建了两个对象,c1 和 c2。
对于对象 c3,我们将 c2 传递给 c1.go() 方法。 并将其设置为 null 并将返回的对象分配给 c3。
在方法 c1.go() 中,cb 所指的对象(据我所知,与 c2 所指的对象相同)被设置为 null。 这不会使 c2 所指的对象也可用于垃圾收集吗?
Java 是按值传递的。 当你做CardBoard c3 = c1.go(c2);
, c2
指向的实例被传递给go()
但是当你做cb=null
,原始c2's cb
没有设置为null
,一个新的空引用aconst_null
被推送到堆栈上并返回。 因此,只有 2 个对象( Short
和c1
)符合 GC 的条件。
PS:正如 Andreas 所说, Short
值缓存在 -128 和 127 之间的值,因此在您的情况下,将重用相同的Short
实例。 所以只有一个对象有资格进行 GC。 如果您的Short
值超出该范围,则 2 个对象将符合 GC 的条件。
Java 是按值传递的,因此当您将参数cb
null 时,不会更改变量c2
的值。
go()
方法调用最终只返回null
,而c1
和c2
保持不变。
因此,当执行到// do stuff
, c1
为空, c2
指的是第二个对象,而c3
为空。 这意味着第一个对象有资格进行 GC。
由于每个对象都有一个Short
引用,您会认为两个对象将被释放(第一个对象及其story
),两个对象将保留(第二个对象及其story
),但事实并非如此。
Short
值为 5 不会创建Short
对象的新实例。 -128 和 127(含)之间的值被缓存,并且缓存值是永久的。
这意味着真正的答案是只分配了 2 个对象,并且第一个对象有资格进行 GC。 Short story
参考不分配任何东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.