简体   繁体   English

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

[英]why the following object is not eligible for garbage collection?

In the following code below ,I didn't understand why the object created with reference b2 is not null ??. 在下面的以下代码中,我不明白为什么使用引用b2创建的对象不是null As I have made the b2 = null by passing it to the go() method of the b1 's object(before making the b1 = 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());

    }

}

So please someone explain me why b2 was not garbage collected even making it null? 因此,请有人向我解释为什么即使将b2设为null也不收集垃圾?

demo b3 = b1.go(b2);

Demo go(Demo cb){
    cb = null;
    return cb;
}

With the above code, the First both b2 and cb will be pointing to the same object. 使用上面的代码,第一个b2cb都将指向同一对象。 Then when you do the cb = null; 然后当你做cb = null; then the cb , reference is lost. 然后cb ,引用丢失。 But b2 is still pointing to the original object. 但是b2仍然指向原始对象。

Which mean that at least one object ( b2 ) is actively holding the reference to the allocated memory/object. 这意味着至少一个对象( b2 )正在主动保存对已分配内存/对象的引用。 It will not be eligible for garbage collection. 它不符合垃圾收集的条件。

Setting any object to null reference does not mean that it is collected by garbage collector. 将任何对象设置为null引用并不意味着它由垃圾收集器收集。 It just mean that, now there are no active reference to the allocated object, so it is eligible for garbage collection. 这只是意味着,现在没有对分配对象的活动引用,因此可以进行垃圾回收。

You first need to know that garbage collection (GC) is not the same as setting something to null. 首先,您需要知道垃圾回收(GC)与将某些内容设置为null不同。

Let me do an analogy here. 让我在这里做个比喻。 The variables ( b1 , b2 , b3 etc) are like children. 变量( b1b2b3等)就像孩子。 And the objects ( new Demo() ) are like balloons. 对象( new Demo() )就像气球。 When you write: 当你写:

demo b1 = new demo();

You make the child b1 hold a new balloon. 您让孩子b1抱着一个新气球。 When you set b1 to null, you make the child let go of his balloon. 当将b1设置为null时,会让孩子放开气球。 The balloon flies away, but it still exists somewhere in the sky. 气球飞走了,但它仍然存在于天空中的某个地方。 On the other hand, GC is like a super hi-tech machine that is able to catch these flying balloons. 另一方面,GC就像是一台能够捕捉这些飞行气球的超级高科技机器。 After the child let go of the balloon, GC notices it after some time (this "time" may vary) and goes to collect it and destroys it. 孩子放开气球后,GC会在一段时间后注意到它(此“时间”可能会有所不同),然后去收集并销毁它。

Now that you learned the difference between nullity and GC, we can go on to your real problem. 既然您已经了解了无效和GC之间的区别,那么我们可以继续讨论您的实际问题。 In the method 在方法中

Demo go(Demo cb){
    cb = null;
    return cb;
}

You are setting cb to null and returning it. 您正在将cb设置为null并返回它。 The return value is null. 返回值为空。 However, cb is not the child you passed in earlier ( b2 ). 但是, cb不是您先前传入的子级( b2 )。 You have a child who is holding a balloon ( b2 ) and when you "pass the child in as a parameter", you are not passing the child, you are inviting another child to hold on to the same balloon. 您有一个正在拿着气球的孩子( b2 ),并且当您“将孩子作为参数传递”时,您没有在传递孩子,而是邀请另一个孩子继续使用同一气球。 In the method, cb is the another child. 在该方法中, cb是另一个孩子。 So when set cb to null, you are letting the "another child" let go of the balloon, but the original child b2 is still holding it. 因此,当将cb设置为null时,您放开了“另一个孩子”气球,但是原始孩子b2仍然持有它。

See? 看到? b2 is still holding the balloon! b2仍然拿着气球! He is not null! 他不是空的!

Because cb points to the same object that b2 does, but cb is NOT the same variable as b2. 因为cb指向与b2相同的对象,但是cb与b2不同。 Setting cb to null does nothing to b2 or to the object pointed to by b2. 将cb设置为null不会对b2或b2指向的对象产生任何影响。

That is not how garbage collection works. 那不是垃圾收集的工作方式。 The garbage collector will find objects that no longer have any references to them, and collect them. 垃圾收集器将找到不再有任何引用的对象,并进行收集。 It will not collect objects that still have references to them, and it will not set any variables to null. 不会收集仍然有引用的对象,也不会将任何变量设置为null。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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