我正在尝试在Scala中编写一个Stream,但我不明白为什么它会在内存中保留一些中间对象(并最终使内存不足)。
以下是我的代码的简化版本:
val slols = {
def genLols (curr:Vector[Int]) :Stream[Int] = 0 #:: genLols(curr map (_ + 1))
genLols(List.fill(1000 * 1000)(0).toVector)
}
println(slols(1000))
这似乎在内存中保留了中间人curr
,我不明白为什么。
这是用迭代器编写的相同代码(更好的内存消耗):
val ilols = new Iterator [Int] {
var curr = List.fill(1000 * 1000)(0).toVector
def hasNext = true
def next () :Int = { curr = curr map (_ + 1) ; 0 }
}
val silols = ilols.toStream
println(silols(1000))
编辑:我有兴趣将0
保留在内存中,我的目标是不保留curr
s,因为它们对于采取计算步骤是有用的(可能不是很明显)在我的简化例子中)。仅0
s就不会出现内存不足错误(它们存储起来并不那么重)。
答案 0 :(得分:2)
将流分配给变量时,可以防止它被垃圾收集。
在第一种情况下,这意味着每次迭代的cur
向量的所有引用都被记忆。
在第二种情况下情况更好,因为迭代器一次只存储cur
的单个实例。但是,流的所有Int
元素都会被记忆。
如果您不需要记忆,请尝试将val slols
替换为def slols
。
顺便说一句,你的两个例子在逻辑方面并不相同(可能你已经意识到了)。
查看this article了解详情。