Scala流将中间对象保留在内存中

时间:2016-06-15 16:55:32

标签: scala stream stack-overflow memoization

我正在尝试在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就不会出现内存不足错误(它们存储起来并不那么重)。

1 个答案:

答案 0 :(得分:2)

将流分配给变量时,可以防止它被垃圾收集。

在第一种情况下,这意味着每次迭代的cur向量的所有引用都被记忆。

在第二种情况下情况更好,因为迭代器一次只存储cur的单个实例。但是,流的所有Int元素都会被记忆。

如果您不需要记忆,请尝试将val slols替换为def slols

顺便说一句,你的两个例子在逻辑方面并不相同(可能你已经意识到了)。

查看this article了解详情。