Scala流和它们的内存使用情况

Mic*_*ael 12 scala stream

据我了解,Stream保留最近评估的元素.我想它不会保留所有评估的元素(这是不可行的),因此它可能使用一些内部"缓存".

这是对的吗?我可以控制此缓存的大小和策略吗?

Dan*_*mon 12

流类似于在需要时生成其成员的列表.生成元素后,它将保留在流中并重新使用.

例如:

lazy val naturals: Stream[Int] = Stream.cons(0, naturals.map{_ + 1})
Run Code Online (Sandbox Code Playgroud)

会给你一个自然数的流.如果我打电话

naturals(5)
Run Code Online (Sandbox Code Playgroud)

它将生成元素0-5并返回5,如果我然后调用

naturals(8)
Run Code Online (Sandbox Code Playgroud)

它将重用前6个元素并生成3个元素.

如果您担心内存使用情况,可以使用从头开始删除元素Stream.drop(num)的新流num,允许使用旧流对截断的元素进行垃圾回收.例如:

naturals(5) //returns 5
val truncated = naturals.drop(4)
truncated(5) //returns 9
Run Code Online (Sandbox Code Playgroud)

  • 但是,只要`naturals`仍然指向流的头部,那些前五个元素将不会被垃圾收集. (6认同)

zig*_*tar 6

Stream-object保留到目前为止已经评估/访问的所有引用.Stream就像一个List.可以从保持的引用到达的每个元素,以及至少已经访问过一次的元素都不会被垃圾回收.

所以基本上你指向流的指针和你目前评估的内容定义了什么将被缓存.

  • 这就是为什么你应该_永远_保持对任何流的引用。始终使用 `def` 定义它们。另见 http://stackoverflow.com/questions/12486762/scala-tail-recursive-stream-processor-function-defined-in-trait-holds-reference 和 http://stackoverflow.com/questions/12529697/how-写入非泄漏尾递归函数使用流cons-in-scala (2认同)