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。