java Collection.sort()的内存消耗

时间:2015-09-24 07:04:06

标签: java sorting memory collections heap-memory

我有一个ArrayList,里面装满了150万个类的对象。当我通过使用Collection.sort方法对此列表进行排序时,JVM的已分配内存会急剧增加。

所以我的问题是:

这是正常的吗?可能是什么原因?这是垃圾收集器工作得太慢还是不经常启动的问题?列表中的对象是否必须满足某些规范才能在排序期间消耗更少的内存(除了不包含那么多数据)?

THX!

1 个答案:

答案 0 :(得分:4)

为了对List进行排序,default sorting implementation首先创建要排序的所有元素的数组副本。这会导致您在排序时观察到额外的堆消耗。这种复制是必要的,因为通用排序算法不知道列表的结构,例如,如果它是随机访问的。

对于Java 8,sorting implementation was however changed被委派给List的每个实现。使用默认方法可以实现这一点。对于ArrayList,通过实施更有效的排序算法,这个额外的开销could be removed。因此,升级到Java 8很可能会解决您的问题。

您的问题垃圾收集没有问题。不幸的是,大型阵列很难处理,因为它们可能不适合年轻一代,最终可以触发完整的收集。

此外,正如评论中所述,Arrays::sort实施的实际排序为performed via Tim Sort since Java 7 Tim sort 需要额外的堆空间。来自javadoc:

  

临时存储要求从近似排序的小常量变化   输入数组到n / 2个对象引用,用于随机排序的输入数组。

如果这不适用于您的用例,您可以通过将系统属性java.util.Arrays.useLegacyMergeSort设置为true来切换回上一个合并排序实现。

毕竟, Tim sort 仍然比合并排序更有效,因为合并排序需要另一个完整的数组副本。