在我的OCJP学习,我碰到以下问题:
class CardBoard {
Short story = 200;
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
}}
//达到doStuff时,有多少个对象资格GC?
正确答案是2,这意味着c1
和story
的对象。
当达到行// doStuff,C3也为空。 为什么不是符合GC吗?
C3是本地手柄,空引用,它并不指向(和赫弗指出)已分配对象。 因此没有什么GC。
c3
是不是对象。 这是一个变量引用无效。 变量可以没有资格GC。 只有对象资格GC。
资格GC的对象是其最初被引用的纸板c1
,短实例最初由纸板引用最初引用的c1
。
对于存储器中的对象的垃圾收集器的扫描,并且当它找到一个检查指向它(而不是反之亦然)当垃圾收集器调用的对象(内部存储器),其具有无柄指向它们被从内存中删除句柄。 在这种情况下的代码,你只需要在内存中创建2个对象不过三个把手。 垃圾收集器将只删除在最大2个对象(因为只有两个对象存在)C3仅在零位指向。 C1,C2,C3不会被删除。 他们用来指向的对象(在他们的情况下,没有其他的手柄点)将被删除。 所以在这一点,因为C3从未指出,在内存中的对象将其设置为空不会使垃圾收集器的差异。
希望我是有帮助
你的CardBoard#go()
方法不起作用。 它接收参考一些对象,立即忘记它,通过更换null
,并返回此null
值。
因此,行
CardBoard c3 = c1.go(c2);
也什么都不做,即没有创建对象。 只是空分配到c3
。 因此,这不是因为收集已不存在,那么垃圾。
所述C3本身只是一个参考变量 ,它是不是在堆空间 (即,不是在垃圾收集的范围)
行CardBoard c3 = c1.go(c2);
只设置C3引用设置为null因此C3垃圾回收并没有影响,因为它不会使任何对象资格。
C3拥有一个对象的引用,它只是做一些混乱。
我们已经创建了两个对象C1和C2,我们错过了为short类型的包装对象,所以基本上我们共创建了四个对象。
当我们正在C1 = null,则意味着,我们使用C1访问短对象可用于GC,而不是短对象,我们可以访问使用C2。
这可以使用下面的代码进行验证:
公共类纸板{
Short story = 200;
CardBoard go(CardBoard cb) {
cb = null;
return cb;
}
public static void main(String[] args) {
Runtime run = Runtime.getRuntime();
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(c2);
// System.out.println(run.freeMemory());
run.gc();
// System.out.println(run.freeMemory());
c1.story = 100;
System.out.println(c1.story);
c1 = null;
run.gc();
System.out.println(c2.story);
}
}
输出:100 200
这意味着,我们可以从C1访问c1和短篇小说是可进行垃圾回收没有c2的短篇小说。