2015-10-26 78 views
0

我遇到了Java堆空間的問題,我在其中試圖將一個數組的連續元素分組以創建用於計算其轉置的矩陣。我有很多值的陣列(26726400)中,我嘗試有大小29水桶但是當我測試下面的代碼,我得到的異常java.lang.OutOfMemoryError: Java heap space在不增加堆空間的情況下避免java.lang.OutOfMemoryError異常?

val arr = new Array[Int](256 * 3600 * 29) 
    arr: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,... 
scala> arr.grouped(29).toArray 
java.lang.OutOfMemoryError: Java heap space 

我的目的是轉置矩陣。如果我運行sbt -mem 2048,此代碼可以工作,但它是另一種執行此任務而不增加堆空間的方法嗎?

回答

1

這可能不會節省很多的內存,雖然它比grouped,這確實緩衝區之間的情侶副本內部肯定更有效。

scala> val arr = new Array[Int](256 * 3600 * 29) 
arr: Array[Int] = Array(0, 0, 0,... 

scala> Array.tabulate(256 * 3600, 29)((i,j) => arr(i * 29 + j)) 
res0: Array[Array[Int]] = Array(Array(0, 0, 0,... 

這在我的科學試驗中速度明顯加快。

您也可以使用1-dim tabulate,分配Array.ofDim(29)Array.copy

0

那麼,對於一個JVM實例的默認存儲器上的機器具有> 1Gb的RAM是RAM/4。所以,爲你的電腦增加更多的內存,你不必將這個參數傳遞給sbt。

說笑歸說笑,你在這裏的數據的至少3份。首先是原始的arr實例,然後運行grouped的結果,然後調用toArray的結果。它甚至可能更多,我不確定隱式轉換爲ArrayOps,通過調用grouped方法(實際上它沒有在Array類中定義)需要此方法。

鑑於你的數據的大小和類型,其中一份大約需要101MB的內存,但不包括與存儲相關的任何開銷。要解決該問題,請減少您製作的副本數量。例如,我不太明白爲什麼你需要最後的toArray電話。

作爲一個側面說明,如果它不是一門功課,考慮使用一些現有的庫矩陣運算,像jBLAS。

+0

我調用'toArray'是因爲我需要在2D數組上應用函數'transpose'。 – alifirat

相關問題