【问题标题】:Does the List subList() method prevent garbage collection of the rest of the list?List subList() 方法是否会阻止对列表的其余部分进行垃圾收集?
【发布时间】:2010-11-14 19:32:20
【问题描述】:

我很想知道最新的 JVM 将如何处理由以下方法保留的垃圾收集内存。

public List<Player> getHallOfFame() {
  ArrayList<Player> listToSort = new ArrayList<Player>(map.values());
  Collections.sort(listToSort, comparator);

  return listToSort.subList(0, 5);
}

在最坏的情况下,我可以想象 JVM 将 listToSort 的全部内容保留在内存中,只要仍然存在对子列表的引用。有谁知道事实是否如此?我对可以为特定 JVM 证明一种或另一种方式的链接特别感兴趣。

【问题讨论】:

  • 我认为 .subList 返回一个新列表,而 listToSort 将超出范围,因此会被垃圾收集。
  • @Paul:文档另有说明。
  • 是的,这里的关键是它由原始列表支持,因此原始列表中的任何更改都会反映在子列表中。
  • 好吧,@Jon,我总是说,当你要做出不知情的猜测时,你(意思是我)应该在评论而不是答案中进行。 :-)

标签: java garbage-collection


【解决方案1】:

是的,subList 只是现有列表的“视图”。所有数据都在原始列表中。来自文档:

返回的列表是由这个列表支持的,所以返回列表中的非结构性变化会反映在这个列表中,反之亦然。

所以是的,返回子列表将使原始列表不会被垃圾收集。

如果你不想要那种效果,你基本上需要制作一个相关子列表的副本。例如:

return new ArrayList<Player>(listToSort.subList(0, 5));

【讨论】:

  • 谢谢乔恩。我认为情况可能有所不同的唯一原因是静态分析可能表明无法再更改原始列表。
  • @Caoilte:反射之类的东西让这样的分析变得非常困难。
【解决方案2】:

subList 创建AbstractList.SubList 的新实例,它保留对原始列表的引用。所以如果你保留getHallOfFame返回的变量,它会阻止gc清理listToSort

【讨论】:

    【解决方案3】:

    我认为你是对的。由于子列表由原始列表支持。来自 java 文档:

    返回此部分的视图 指定 fromIndex 之间的列表, 包含和 toIndex ,不包含。 (如果 fromIndex 和 toIndex 相等,则 返回的列表为空。)返回的 列表由这个列表支持,所以 返回的非结构性变化 列表反映在此列表中,并且 反之亦然。返回列表支持 所有可选的列表操作 此列表支持。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-04
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      • 2015-10-08
      • 2020-01-15
      相关资源
      最近更新 更多