2016-08-12 108 views
1

我試圖使用範圍來實現迭代算法。它運行良好,所以我試圖使用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

我想你已經發現了怎樣的一個 「錯誤」 的。

更多的細節。

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