5

我想知道您是否认为删除对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?
   }
}
4

7 回答 7

8

通常它是不需要的。

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

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

但是,如果您发现自己处于这种情况,我怀疑您无论如何都有设计气味:为什么内部对象与封闭对象具有如此不同的范围/生命周期?这让我很怀疑,因为通常当您使用组合构建对象图时,您希望组合对象具有相似的生命周期。

于 2013-04-16T10:50:13.973 回答
2

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

于 2013-04-16T10:52:56.873 回答
0

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

于 2013-04-16T10:49:12.457 回答
0

不,这是不必要的。只要heavyObject1 超出范围,它就会被标记为GC。

于 2013-04-16T10:49:46.483 回答
0

null不,这对田野或当地人来说通常不是好的做法。

在大多数情况下,您要清空其字段的对象在 GC 运行之前将变得不可访问。如果发生这种情况,您将对象字段归零所花费的 CPU 周期将被浪费。

唯一需要/对null字段/本地人有益的情况是:

  1. 当GC 运行时,父对象可能仍然可以访问,并且
  2. 子对象(图)足够大,以使保留的内存量很大……相对于总堆大小。

如果您正在实现一个旨在用于各种情况的类,您也可以这样做......其中一些情况可能符合上述标准。(例如,实例可能会变大的数据结构实现。)

于 2013-04-16T11:23:37.867 回答
0

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

于 2013-04-16T11:26:33.067 回答
0

作为一般做法,不,因为它不是必需的。

有一些特殊情况——我可以想象一个长期存在的类,例如,它有一个长长的内存消耗对象列表,它使用这些对象执行一次操作,然后等待一段时间,然后再用另一个列表替换该列表。最好在等待时将列表清空,不会伤害任何东西,并且可能会阻止程序不得不同时结束两个列表。

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

请不要鼓励人们对此制定“规则”。当我想到我读过的所有代码时,有人将“final”放在(几乎)所有(他们认为)在初始化后不会改变的变量之前,这使得代码的可读性降低并让我相信程序员有不了解他们所谓的速度改进......

于 2013-04-16T11:03:12.167 回答