Scala ParRange内存消耗
问题描述:
我试图使用范围来实现迭代算法。它运行良好,所以我试图使用par方法进行并行处理,并抛出了java.lang.OutOfMemoryError:Java堆空间。我发现ParRange在构造函数中分配了很多内存。这是ParRange的正确行为吗?我希望它的行为与Range相似,只在需要时才分配数据。Scala ParRange内存消耗
您可以轻松地重现:
scala> collection.parallel.immutable.ParRange(1, 50000000, 1, true) java.lang.OutOfMemoryError: Java heap space
答
我想你已经发现了怎样的一个 “错误” 的。
更多的细节。
如果你看一看到OOM堆栈跟踪更准确 - 斯卡拉(对于一些未知的原因)是在
ParRange.scala:35
类调用简单toString
方法。 5千万个数字连接在一起形成一个巨大的字符串,使得你比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...
}
}