简体   繁体   中英

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

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.

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). And the 0 s alone cannot make an out of memory error (they are not so heavy to store).

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.

In second case the situation is better, as iterator stores only single instance of cur at a time. But still, all Int elements of the stream are memoized.

Try replacing val slols with def slols if you don't need memoization.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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