繁体   English   中英

作为参数传递并在方法中设置为 null 的对象的垃圾收集

[英]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 个对象( Shortc1 )符合 GC 的条件。

PS:正如 Andreas 所说, Short值缓存在 -128 和 127 之间的值,因此在您的情况下,将重用相同的Short实例。 所以只有一个对象有资格进行 GC。 如果您的Short值超出该范围,则 2 个对象将符合 GC 的条件。

Java 是按值传递的,因此当您将参数cb null 时,不会更改变量c2的值。

go()方法调用最终只返回null ,而c1c2保持不变。

因此,当执行到// do stuffc1为空, c2指的是第二个对象,而c3为空。 这意味着第一个对象有资格进行 GC。


由于每个对象都有一个Short引用,您会认为两个对象将被释放(第一个对象及其story ),两个对象将保留(第二个对象及其story ),但事实并非如此。

Short值为 5 不会创建Short对象的新实例。 -128 和 127(含)之间的值被缓存,并且缓存值是永久的。

这意味着真正的答案是只分配了 2 个对象,并且第一个对象有资格进行 GC。 Short story参考不分配任何东西。

暂无
暂无

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

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