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

时间:2016-09-24 14:31:51

标签: java garbage-collection

我试图理解这个问题,但无法通过书中提供的答案得到解决。有人可以向我解释一下吗?问题如下。

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
  }
}

当//达到了什么东西时,有多少对象可以进行垃圾回收?

答案是 2个对象。只有一个CardBoard对象(c1)符合条件,但它有一个相关的Short包装器对象,也符合条件

我不明白为什么单独的对象c1有资格进行垃圾回收。

创建了两个对象,c1和c2。

对于对象c3,我们将c2传递给c1.go()方法。并且将其设置为null并将返回的对象赋予c3。

在方法c1.go()中,cb reffering(通过我的承诺,与c2相同的对象)被设置为null的对象。那不会使c2 reffering的对象也可用于垃圾收集吗?

2 个答案:

答案 0 :(得分:0)

Java是按值传递。当您执行CardBoard c3 = c1.go(c2);时,c2指向的实例会传递到go(),但是当您执行cb=null时,原始c2's cb未设置为{ {1}},新的空引用null被压入堆栈并返回。因此,只有2个对象(aconst_nullShort)符合GC条件。

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

答案 1 :(得分:0)

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

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

因此,当执行到// do stuff时,c1为空,c2引用第二个对象,c3为空。这意味着第一个对象符合GC的条件。

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

story值为5将不会创建Short对象的新实例。 -128和127之间的值(包括)缓存,缓存值是永久值。

这意味着真正的答案是只分配了2个对象,并且第一个对象符合GC的条件。 Short引用不会分配任何内容。