Lambda 在无穷无尽的流中捕获带有 Integer 的闭包抛出 OutOfMemoryError
Lambda capturing closure with Integer in endless stream throws OutOfMemoryError
低于 100% 的代码抛出 java.lang.OutOfMemoryError
Set<Integer> set = new HashSet<>();
new Random().ints(10_000_000,
Integer.MIN_VALUE,
Integer.MAX_VALUE)
.forEach(
v -> {
if(set.contains(v)){
System.out.println(v);
}else{
set.add(v);
}
}
);
据我所知,这是因为 lambda 使用上下文捕获整数?谁能解释一下这里究竟发生了什么?
在您的代码中,您有 Set
可以通过 main
方法访问。本地堆栈是一个GC根,所以它不能被GC回收。
因此,您正在向集合中添加无法收集的元素。并且 set 需要额外的内存来存储元素。
在我的 PC 上,运行 这个程序没有 OOM 需要大约 600 MB 的堆。
这里是这个程序的堆转储 运行ning 在我的电脑上。
我用普通 for
循环尝试了相同的代码并得到了相同的结果。
因此您只需要为您的应用程序添加更多内存。例如 -Xmx1g
会将您的堆大小设置为 1 GB。
低于 100% 的代码抛出 java.lang.OutOfMemoryError
Set<Integer> set = new HashSet<>();
new Random().ints(10_000_000,
Integer.MIN_VALUE,
Integer.MAX_VALUE)
.forEach(
v -> {
if(set.contains(v)){
System.out.println(v);
}else{
set.add(v);
}
}
);
据我所知,这是因为 lambda 使用上下文捕获整数?谁能解释一下这里究竟发生了什么?
在您的代码中,您有 Set
可以通过 main
方法访问。本地堆栈是一个GC根,所以它不能被GC回收。
因此,您正在向集合中添加无法收集的元素。并且 set 需要额外的内存来存储元素。
在我的 PC 上,运行 这个程序没有 OOM 需要大约 600 MB 的堆。
这里是这个程序的堆转储 运行ning 在我的电脑上。
我用普通 for
循环尝试了相同的代码并得到了相同的结果。
因此您只需要为您的应用程序添加更多内存。例如 -Xmx1g
会将您的堆大小设置为 1 GB。