繁体   English   中英

为什么以下对象不符合垃圾回收条件?

[英]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;
}

使用上面的代码,第一个b2cb都将指向同一对象。 然后当你做cb = null; 然后cb ,引用丢失。 但是b2仍然指向原始对象。

这意味着至少一个对象( b2 )正在主动保存对已分配内存/对象的引用。 它不符合垃圾收集的条件。

将任何对象设置为null引用并不意味着它由垃圾收集器收集。 这只是意味着,现在没有对分配对象的活动引用,因此可以进行垃圾回收。

首先,您需要知道垃圾回收(GC)与将某些内容设置为null不同。

让我在这里做个比喻。 变量( b1b2b3等)就像孩子。 对象( 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM