Scala ParRange内存消耗

时间:2016-08-12 12:28:34

标签: scala

我尝试使用范围实现迭代算法。它运行良好所以我尝试使用par方法使其并行,并抛出 java.lang.OutOfMemoryError:Java堆空间。我发现ParRange在构造函数中分配了大量内存。这是ParRange的正确行为吗?我希望它的行为与Range类似,只在需要时分配数据。

您可以轻松复制它:

scala> collection.parallel.immutable.ParRange(1, 50000000, 1, true) java.lang.OutOfMemoryError: Java heap space

1 个答案:

答案 0 :(得分:1)

我认为你发现了一种“错误”。

更多细节。

  1. 如果您更精确地研究OOM堆栈跟踪 - scala(由于某种未知原因)在toString类上调用简单的ParRange.scala:35方法。将5000万个数字连接成一个巨大的字符串,比Gb更多,并导致OOM。

  2. OOM仅在console执行时发生。使用main的简单独立应用可以正常工作(除非您在其上调用toString)...

  3. Range怎么样?实际上,使用Range代替ParRange的相同代码完全可行。原因很简单:toString方法在那里被覆盖,并且不要尝试输出所有元素,而只是前几个......

  4. 我建议您按照解决方法使代码正常工作:

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