【问题标题】:Is this java Object eligible for garbage collection in List这个 java 对象是否有资格在 List 中进行垃圾收集
【发布时间】:2013-05-31 05:35:51
【问题描述】:

我的问题可能是一个愚蠢的问题,所以请原谅我。 所以它是这样的:

List<Boss> bossList = new ArrayList<Boss>();
Boss b = null;
for(Employee e : List<Employee> myList){
    b = new Boss();
    b.setEmployee(e);
    bossList.add(b);
    b = null;
}

所以在上面的场景中,我创建了很多 Boss 对象,然后取消引用它们(我知道我不需要写“b = null”,但我这样做是为了清楚我的问题)。在正常情况下,我会通过这样做将它们标记为垃圾回收,但是因为在这种情况下,我将这些 Boss 对象添加到 List 集合中,它们是否标记为 GC?如果不是那为什么?以及 List 收集如何在内部工作以保存每个添加的 Object 的引用,从而避免垃圾收集?

[EDIT] 

问题的范围仅限于for循环中创建的各个Boss对象,考虑到该方法会将List的引用返回给外界。

【问题讨论】:

  • 您放入列表中的对象本身显然不能用于 GC,因为对它的引用仍然存在,即使您将 b 无效。
  • 如果在当前程序状态下有任何方法可以访问一个对象(不包括通过特殊类 WeakReference 及其相关类),则该对象不能被垃圾回收。无论在哪里,来自实时代码的一个参考就足够了。

标签: java collections arraylist garbage-collection


【解决方案1】:

Boss 对象不会被 GarbageCollector 收集,因为它们仍然在您发布的代码块中被引用。 bossList 是一个 ArrayList,它有一个 Object 的内部数组,因此保存了对添加到其中的那些对象的引用。

在这种情况下,不仅会考虑您的引用,还会考虑所有涉及的对象中的所有引用。

编辑:由于您在代码中返回列表,因此在您的程序中不再引用该列表之前,不会将对象标记为垃圾回收。

【讨论】:

  • 但是由于List&lt;Boss&gt;是在方法内部声明的,所以当方法结束时,列表会被标记为GC,因此Boss对象引用也会被标记。
  • 正确。一旦声明 ArrayList 的块终止,所有对象都将被收集(如果没有进一步引用)。
  • 当然,如果您假设列表仅存在于方法中。
  • @system32 如果这些对象没有在程序的其他部分引用,那么是的,它们将被标记为 GC。
  • @DanielLerps 那么你应该在你的答案中指定这一点,因为 OP 没有在问题中定义这个。
【解决方案2】:

ArrayList 内部有Object[] elementData。当您将b 添加到bossList 时,ArrayList 分配了elementData[0] = b。因此,当您将null 分配给b 时,Boss 的实例仍然从elementData[0] 引用并且不能被GCed。但由于 ArrayList 实例仅在方法返回 ArrayListBoss 实例后才从方法的变量中引用,因此将有资格进行 GC。

【讨论】:

    【解决方案3】:

    以下是您的代码真正发生的情况:

    【讨论】:

      【解决方案4】:

      由于 java 是通过引用传递的,每当您将 b 添加到 bossList 时,bossList 就会开始引用 b 指向的内存位置。因此,当b 无效时,只有从b 到引用的链接被破坏。从而使对象可以通过bossList 访问。

      【讨论】:

        猜你喜欢
        • 2016-12-10
        • 2018-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多