我很想知道最新的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的链接。
答案 0 :(得分:11)
是的,subList
只是现有列表中的“视图”。所有数据都在原始列表中。来自文档:
返回的列表由此列表支持,因此返回列表中的非结构更改将反映在此列表中,反之亦然。
所以是的,返回一个子列表将使原始列表不被垃圾收集。
如果您不想要这种效果,您基本上需要制作相关子列表的副本。例如:
return new ArrayList<Player>(listToSort.subList(0, 5));
答案 1 :(得分:1)
subList
创建AbstractList.SubList
的新实例,该实例保留对原始列表的引用。因此,如果您保留getHallOfFame
返回的变量,则会阻止gc清除listToSort
。
答案 2 :(得分:0)
我认为你是对的。由于子列表由原始列表支持。来自java docs:
返回此部分的视图 指定fromIndex之间的列表, 包容性和toIndex,独家。 (如果 fromIndex和toIndex是相等的, 返回列表为空。)返回 列表由此列表支持,所以 返回的非结构性变化 列表反映在此列表中,并且 反之亦然。返回的列表支持 所有可选的列表操作 此列表支持。