我有一個非常大的數字列表,它經歷了大量的數學操作。我只關心最後的結果。要模擬這種行爲,請參閱下面的示例代碼:斯卡拉的範圍和內存問題
object X {
def main(args:Array[String]) = {
val N = 10000000
val x = List(1 to N).flatten
println(x.slice(0,10))
Thread.sleep(5000)
val y = x.map(_*5)
println(y.slice(0,10))
Thread.sleep(5000)
val z = y.map(_+4)
println(z.slice(0,10))
Thread.sleep(5000)
}
}
所以x是一個非常大的列表。我只關心結果z。爲了獲得z,我首先必須用數學方法處理x來得到y。然後我操縱y得到z。 (我不能一步一步從x到z,因爲操作很複雜,這只是一個例子)
所以當我運行這個例子時,內存不足大概是因爲x,y和z是都在範圍內,他們都佔有記憶。
所以我嘗試以下方法:
def main(args:Array[String]) = {
val N = 10000000
val z = {
val y = {
val x = List(1 to N).flatten
println(x.slice(0,10))
Thread.sleep(5000)
x
}.map(_*5)
println(y.slice(0,10))
Thread.sleep(5000)
y
}.map(_+4)
println(z.slice(0,10))
Thread.sleep(5000)
}
所以現在只有Z是在範圍之內。所以大概x和y被創建,然後當它們超出範圍時收集垃圾。但這不是發生的事情。相反,我再次用光了內存!
(注:我用java -Xincgc,但它並不能幫助)
問題:當我有足夠的內存只有1大名單,可我不知用操縱它只是VAL的(即沒有可變變量或ListBuffers),也許使用範圍來強制gc?如果是這樣,怎麼樣? 謝謝
您將始終需要兩個列表的內存。出於好奇,你有沒有設置你的Java堆?考慮'陣列'? –
沒錯,我總是需要2個列表的內存,這是我的。 但我不應該需要內存3列表,我沒有。 你同意嗎? 在任何情況下,由於x和y超出範圍,爲什麼一旦VM發現內存不足並且變量不在範圍內,它們就不會被垃圾回收? –