简体   繁体   English

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

[英]Scala stream keeps intermediary objects in memory

I am trying to write a Stream in Scala and I do not get why it keeps some intermediary objects in memory (and eventually get out of memory). 我正在尝试在Scala中编写Stream,但我不明白为什么它会在内存中保留一些中间对象(并最终导致内存不足)。

Here is a simplified version of my code : 这是我的代码的简化版本:

val slols = {
  def genLols (curr:Vector[Int]) :Stream[Int] = 0 #:: genLols(curr map (_ + 1))
  genLols(List.fill(1000 * 1000)(0).toVector)
}
println(slols(1000))

This seems to keep in memory the intermediary curr and I do not see why. 这似乎保留在中间curr ,我不明白为什么。

Here is the same code written with an iterator (much better memory consumption): 这是用迭代器编写的相同代码(更好的内存消耗):

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))

EDIT : I am interested in keeping the 0 s in memory, my goal is to not keep the curr s because they are juste useful to take a step of computation (it may not be obvious in my simplified example). 编辑:我有兴趣在内存中保留0 s,我的目标是不保留curr因为它们对于采取计算步骤很有用(在我的简化示例中可能并不明显)。 And the 0 s alone cannot make an out of memory error (they are not so heavy to store). 而且仅凭0就不会造成内存不足错误(它们存储起来并不那么繁重)。

When you assign stream to a variable you prevent it's head from being garbage collected. 当您将流分配给变量时,可以防止其头部被垃圾回收。

In first case that means that all the references for cur Vectors for each iteration are memoized. 在第一种情况下,意味着每次迭代的cur Vector的所有引用都被记忆。

In second case the situation is better, as iterator stores only single instance of cur at a time. 在第二种情况下,情况更好,因为迭代器一次只存储cur的一个实例。 But still, all Int elements of the stream are memoized. 但是仍然会记住流中的所有Int元素。

Try replacing val slols with def slols if you don't need memoization. 如果不需要记忆,请尝试用def slols替换val slols

And by the way, your two examples are not equivalent in terms of logic (probably you're aware of it). 顺便说一句,就逻辑而言,您的两个示例并不相同(可能您已经意识到了)。

Check this article for details. 查看本文以了解详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM