删除引用以帮助GC是一个好习惯吗?

时间:2013-04-16 10:45:44

标签: java garbage-collection

我想知道您是否认为将引用(将它们设置为null)移除到对象以帮助Java垃圾收集器是一种很好的做法。

例如,假设您有一个包含两个字段的类,其中一个字段非常耗费内存。如果您知道只需要进行特定处理,则可以在之后立即将其置空以帮助GC。

假设我真的需要这两个字段,而不仅仅是内部变量,因此heavyObject1不能超出方法末尾的范围。

你会这样做作为一般做法吗?

public class TestClass {

   public static Object heavyObject1;
   public static Object object2;

   private static void action() {
    object2 = doSomething(heavyObject1);

    heavyObject1 = null; //is this good?
   }
}

7 个答案:

答案 0 :(得分:8)

通常不需要。

在以下特定情况下,这是一个好主意:

  • 对象很大(即足以让您关心
  • 您确定不再需要对象
  • 对象不会超出范围(例如,您知道周围的对象不会被垃圾收集)

但是,如果你发现自己处于这种情况,我怀疑你有一种设计气味:为什么内部物体与封闭物体有不同的范围/寿命?这让我很怀疑,因为通常在构建带有合成的对象图时,您希望组合对象具有相似的生命周期。

答案 1 :(得分:2)

在大多数情况下,您不需要将对象设置为null以进行垃圾回收。如果您在适当的范围(方法级别,实例级别或类级别)中对对象进行十分转换,则该对象将无法访问使用后立即有资格进行垃圾收集。

答案 2 :(得分:0)

如果您不想再使用该对象,那么将null分配给引用肯定是不良做法。但是,不好的做法,指望GC在程序执行期间的任何时候或根本收集它们。

答案 3 :(得分:0)

不,这是不必要的。只要heavyObject1没有作用域,它就会被标记为GC。

答案 4 :(得分:0)

作为一般练习,不,因为不需要。

有一些特殊情况 - 例如,我可以想象一个长期存在的类,它有一个很长的内存消耗对象列表,它一次做一些事情,然后在用另一个列表替换该列表之前等待一段时间。在你等待的时候,也可以使列表无效,不会伤害任何内容,并且可能会阻止程序同时以两个列表结束。

但其中又有“不需要”的原则。您不能指望GC在特定时间段内运行,因此程序需要支持同时在堆上同时使用这两个列表,因此如果之前不是这样,它就不会使您的程序可行。

让我们不要鼓励人们对此做出“规则”。当我想到我读过的所有代码时,有人把“最终”放在(几乎)所有变量之前(他们认为)在初始化后不会改变,使得代码的可读性降低,并使我相信程序员有不了解他们应该提高的速度......

答案 5 :(得分:0)

没有。 null字段或当地人通常不是好的做法。

在大多数情况下,在GC运行之前,其归零字段的对象将无法访问。如果发生这种情况,那么用于归零对象字段的CPU周期将被浪费。

null字段/本地的必要/好的唯一情况是:

  1. 可能在GC运行时仍然可以访问父对象,AND
  2. 子对象(图形)足够大,相对于总堆大小,保留的内存量很大......
  3. 如果您正在实现一个预期的类以便在各种情况下使用,您也可以这样做......并且其中一些情况符合上述标准。 (例如,实例可能变大的数据结构实现。)

答案 6 :(得分:0)

除非您的类正在管理自己的内存或者您的类正在缓存资源,否则不需要取消引用对象,那么应该删除过时的引用。