提问人:J.J. Beam 提问时间:11/18/2021 最后编辑:J.J. Beam 更新时间:11/18/2021 访问量:33
在无限流中使用 Integer 捕获闭包的 Lambda 会抛出 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);
}
}
);
AFAIK 这是因为 lambda 捕获带有上下文的整数?谁能解释一下这里到底发生了什么?
答:
1赞
geobreze
11/18/2021
#1
在您的代码中,您可以从方法访问。本地堆栈是 GC 根,因此 GC 无法收集它。Set
main
因此,您正在向集合中添加无法收集的元素。set 需要额外的内存来存储元素。
在我的 PC 上,在没有 OOM 的情况下运行此程序需要大约 600 MB 的堆。
这是在我的电脑上运行的这个程序的堆转储。
我尝试了与香草循环相同的代码并得到了相同的结果。for
因此,您只需要为应用程序添加更多内存即可。例如,将堆大小设置为 1 GB。-Xmx1g
评论
0赞
J.J. Beam
11/18/2021
实际上我是从单元测试开始代码的,它和从 main 方法一样吗?
0赞
geobreze
11/18/2021
是的,从单元测试开始时,您的代码也可以从本地堆栈访问。您可以在 surefire 插件的配置中设置内存设置 stackoverflow.com/a/7579853/4655217
评论
-Xmx128m