【发布时间】:2016-05-19 17:09:11
【问题描述】:
刚刚在我们的生产环境中遇到了一次比较不愉快的经历,导致OutOfMemoryErrors: heapspace..
我将此问题追溯到我在函数中使用ArrayList::new。
为了验证这实际上比通过声明的构造函数 (t -> new ArrayList<>()) 进行的正常创建执行得更差,我编写了以下小方法:
public class TestMain {
public static void main(String[] args) {
boolean newMethod = false;
Map<Integer,List<Integer>> map = new HashMap<>();
int index = 0;
while(true){
if (newMethod) {
map.computeIfAbsent(index, ArrayList::new).add(index);
} else {
map.computeIfAbsent(index, i->new ArrayList<>()).add(index);
}
if (index++ % 100 == 0) {
System.out.println("Reached index "+index);
}
}
}
}
使用newMethod=true; 运行该方法将导致该方法在索引达到30k 后以OutOfMemoryError 失败。使用 newMethod=false; 时,程序不会失败,而是会继续运行直到被杀死(索引轻松达到 150 万)。
为什么ArrayList::new 会在堆上创建这么多Object[] 元素,导致OutOfMemoryError 如此之快?
(顺便说一句 - 当集合类型为 HashSet 时也会发生这种情况。)
【问题讨论】:
-
一个微妙的。 +1 表示容易绊倒的东西...
标签: java constructor java-8 out-of-memory method-reference