【发布时间】:2020-05-17 00:56:04
【问题描述】:
我试图理解为什么下面的 Java 程序给出了OutOfMemoryError,而没有.parallel() 的相应程序却没有。
System.out.println(Stream
.iterate(1, i -> i+1)
.parallel()
.flatMap(n -> Stream.iterate(n, i -> i+n))
.mapToInt(Integer::intValue)
.limit(100_000_000)
.sum()
);
我有两个问题:
-
这个程序的预期输出是什么?
如果没有
.parallel(),这似乎只是输出sum(1+2+3+...),这意味着它只是“卡在”flatMap 中的第一个流,这是有道理的。对于并行,我不知道是否有预期的行为,但我的猜测是它以某种方式交错了第一个
n左右的流,其中n是并行工作者的数量。根据分块/缓冲行为,它也可能略有不同。 -
是什么导致它耗尽内存? 我特别想了解这些流是如何在后台实现的。
我猜有什么东西阻塞了流,所以它永远不会完成并且能够摆脱生成的值,但我不太清楚事物的评估顺序和缓冲发生的位置。
编辑:如果相关,我使用的是 Java 11。
Editt 2: 显然,即使对于简单的程序 IntStream.iterate(1,i->i+1).limit(1000_000_000).parallel().sum(),也会发生同样的事情,所以它可能与 limit 而不是 flatMap 的懒惰有关。
【问题讨论】:
-
parallel() 内部使用 ForkJoinPool。我猜 ForkJoin 框架是从 Java 7 开始的 Java
标签: java java-stream out-of-memory lazy-evaluation