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

我想你已经发现了怎样的一个 “错误” 的。

更多的细节。

  1. 如果你看一看到OOM堆栈跟踪更准确 - 斯卡拉(对于一些未知的原因)是在ParRange.scala:35类调​​用简单toString方法。 5千万个数字连接在一起形成一个巨大的字符串,使得你比Gb更多并导致OOM。

  2. OOM仅在执行console时发生。与main简单的独立应用程序正常工作(除非你调用toString就可以了)...

  3. 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... 
    } 
    }