在 Java 中将对象分配给 null 会影响垃圾回收吗?

新手上路,请多包涵

在 Java 中将未使用的对象引用分配给 null 是否以任何可衡量的方式改进了垃圾收集过程?

我使用 Java(和 C#)的经验告诉我,尝试超越虚拟机或 JIT 编译器通常是违反直觉的,但我看到同事使用这种方法,我很好奇这是否是一个好的实践选择或那些巫毒编程迷信之一?

原文由 James McMahon 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 778
2 个回答

通常,没有。

但就像所有事情一样:这取决于。这些天 Java 中的 GC 非常好,一切都应该在不再可访问后很快清理掉。这是在为局部变量保留方法之后,并且不再为字段引用类实例时。

如果您知道它会在其他情况下保持引用,则只需要显式设置为 null。例如一个保存在周围的数组。当不再需要数组的各个元素时,您可能希望将它们清空。

例如,来自 ArrayList 的这段代码:

 public E remove(int index) {
    RangeCheck(index);

    modCount++;
    E oldValue = (E) elementData[index];

    int numMoved = size - index - 1;
    if (numMoved > 0)
         System.arraycopy(elementData, index+1, elementData, index,
             numMoved);
    elementData[--size] = null; // Let gc do its work

    return oldValue;
}

此外,只要没有引用保留,显式地使一个对象为空不会导致对象比它自然地超出范围更早地被收集。

两个都:

 void foo() {
   Object o = new Object();
   /// do stuff with o
}

和:

 void foo() {
   Object o = new Object();
   /// do stuff with o
   o = null;
}

在功能上是等效的。

原文由 Mark Renouf 发布,翻译遵循 CC BY-SA 2.5 许可协议

根据我的经验,人们常常出于偏执而不是出于必要而取消引用。这是一个快速指南:

  1. 如果对象 A 引用对象 B 并且 您不再需要此引用 并且 对象 A 不符合垃圾收集的条件,那么您应该显式清空该字段。如果封闭对象无论如何都会被垃圾回收,则无需清空字段。在 dispose() 方法中清空字段几乎总是无用的。

  2. 无需清空在方法中创建的对象引用。一旦方法终止,它们将被自动清除。此规则的例外情况是,如果您正在运行一个非常长的方法或一些大循环,并且您需要确保在该方法结束之前清除某些引用。同样,这些情况极为罕见。

我会说绝大多数时候你不需要清空引用。试图智取垃圾收集器是没有用的。您最终只会得到低效、不可读的代码。

原文由 Gili 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题