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

why the following object is not eligible for garbage collection?

在下面的代码中,我不明白为什么引用b2创建的对象不是null??。 因为我通过将 b2 = null 传递给 b1 对象的 go() 方法(在制作 b1 = null 之前)制作了 b2 = 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 没有被垃圾回收,甚至使它为空?

垃圾回收不是这样工作的。垃圾收集器将找到不再有任何引用的对象,并收集它们。它将不会收集仍然引用它们的对象,并且不会将任何变量设置为空。

因为 cb 指向与 b2 相同的对象,但 cb 与 b2 不是同一个变量。将 cb 设置为 null 对 b2 或 b2 指向的对象没有任何作用。

demo b3 = b1.go(b2);

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

使用上面的代码,第一个 b2cb 将指向同一个对象。然后,当您执行 cb = null; 然后执行 cb 时,引用将丢失。但是 b2 仍然指向原来的对象。

这意味着至少一个对象 (b2) 正在主动持有对分配的 memory/object 的引用。它将不符合垃圾收集的条件。

将任何对象设置为 null 引用并不意味着它被垃圾收集器收集。这只是意味着,现在没有对分配对象的活动引用,因此它符合垃圾收集条件。

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

这里我打个比方。变量(b1b2b3 等)就像 children。而 objects (new Demo()) 就像气球一样。当你写:

demo b1 = new demo();

你让 child b1 拿着一个新的气球。当您将 b1 设置为 null 时,您让 child 放开了他的气球。气球飞走了,但它仍然存在于天空的某个地方。另一方面,GC 就像一台超级 hi-tech 机器,能够接住这些飞翔的气球。在 child 放开气球后,GC 会在一段时间后注意到它(这个 "time" 可能会有所不同)并去收集它并销毁它。

既然您了解了 nullity 和 GC 之间的区别,我们可以继续解决您的实际问题。在方法

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

您正在将 cb 设置为 null 并 returning 它。 return 值为空。但是,cb 不是您之前传入的 child (b2)。你有一个 child 拿着气球 (b2),当你 "pass the child in as a parameter",你没有传递 child,你是在邀请另一个 child抓住同一个气球。在该方法中,cb 是另一个 child。所以当设置cb为null时,你是让"another child"放开气球,但是原来的childb2还拿着它。

看到了吗? b2还拿着气球呢!他不为空!