我尝试使用范围实现迭代算法。它运行良好所以我尝试使用par方法使其并行,并抛出 java.lang.OutOfMemoryError:Java堆空间。我发现ParRange在构造函数中分配了大量内存。这是ParRange的正确行为吗?我希望它的行为与Range类似,只在需要时分配数据。
您可以轻松复制它:
scala> collection.parallel.immutable.ParRange(1, 50000000, 1, true)
java.lang.OutOfMemoryError: Java heap space
答案 0 :(得分:1)
我认为你发现了一种“错误”。
更多细节。
如果您更精确地研究OOM堆栈跟踪 - scala(由于某种未知原因)在toString
类上调用简单的ParRange.scala:35
方法。将5000万个数字连接成一个巨大的字符串,比Gb更多,并导致OOM。
OOM仅在console
执行时发生。使用main
的简单独立应用可以正常工作(除非您在其上调用toString
)...
Range
怎么样?实际上,使用Range
代替ParRange
的相同代码完全可行。原因很简单:toString方法在那里被覆盖,并且不要尝试输出所有元素,而只是前几个......
我建议您按照解决方法使代码正常工作:
def parRangeBuilder(start: Int, end: Int, step: Int, include: Boolean) = {
new ParRange(
if (include)
new Range.Inclusive(start, end, step)
else
new Range(start, end, step)
) {
override def toString = s"LazyParRange(${range.size})" // fix itself...
}
}