Scala流迭代和内存管理

Scala流迭代和内存管理,scala,garbage-collection,scala-collections,scala-streams,Scala,Garbage Collection,Scala Collections,Scala Streams,我有以下代码: val res = Stream // launch the real computation, which alternates E and M steps, updating the computation state .iterate(initCompState)(Base.emIteration) .take(nIteration) .last 其思想是提供一个初始状态initCompState,一个从上一个状态生成新状态的函数,为操作运行该函数,并获得最终

我有以下代码:

val res = Stream // launch the real computation, which alternates E and M steps, updating the computation state
  .iterate(initCompState)(Base.emIteration)
  .take(nIteration)
  .last
其思想是提供一个初始状态
initCompState
,一个从上一个状态生成新状态的函数,为
操作运行该函数,并获得最终结果

我不是中间州的人,我希望他们在不需要的时候尽快被垃圾收集。从我在线阅读的内容来看,
Stream
在递归定义值时保留这些值,但这里的情况并非如此


我的实现正确吗?流中的下一个状态计算完成后,
initCompState
res
垃圾之间的中间状态是否立即被收集?

IterableAgain
,这意味着,它将保留您迭代的所有元素,以防您希望再次看到它们

Iterator
更适合您的情况,您可以扫描它一次,因此,只要您查看它,它就会丢弃每个元素。但是它没有
last
,因此,您必须自己用类似于

 iterator.foldLeft(Option.empty[Int])((_, n) => Some(n))
或者,只需递归地实现迭代:

 @tailrec
 def iterate(iters: Int, state: State = initCompState): State = if(iters == 0)
   state 
 else 
   iterate(iters - 1, Base.emIteration(state))

 val result = iterate(nIteration)

Stream
IterableAgain
,这意味着它将保留您迭代的所有元素,以防您想再次看到它们

Iterator
更适合您的情况,您可以扫描它一次,因此,只要您查看它,它就会丢弃每个元素。但是它没有
last
,因此,您必须自己用类似于

 iterator.foldLeft(Option.empty[Int])((_, n) => Some(n))
或者,只需递归地实现迭代:

 @tailrec
 def iterate(iters: Int, state: State = initCompState): State = if(iters == 0)
   state 
 else 
   iterate(iters - 1, Base.emIteration(state))

 val result = iterate(nIteration)

与其使用
Iterator
不如使用
Iterator
因此,当他们说应该使用def而不是val来避免将所有流保留在内存中时,这意味着在对其求值后保留它。在这两种情况下,在评估过程中保留了整个计算值集?我不知道是谁说的。。。为什么:)根据a
流,只有当某个东西抓住头部时,才会将其记忆。使用
def
是避免这种情况的一种方法。所以真正的问题是:
Stream.iterate()?(顺便说一句,它可以直接索引,而不是
take(n)。last
)。@jwvh它确实。。。在流中迭代的代码无法知道是否有人持有对头部的引用,因此它必须保留所经过的所有元素。后来,当引用被丢弃时,那些被记忆的元素也随之被丢弃(前提是它们不是从其他对象引用的)。因此,当他们说应该使用def而不是val来避免将所有流保留在内存中时,这意味着在对其求值后保留它。在这两种情况下,在评估过程中保留了整个计算值集?我不知道是谁说的。。。为什么:)根据a
流,只有当某个东西抓住头部时,才会将其记忆。使用
def
是避免这种情况的一种方法。所以真正的问题是:
Stream.iterate()?(顺便说一句,它可以直接索引,而不是
take(n)。last
)。@jwvh它确实。。。在流中迭代的代码无法知道是否有人持有对头部的引用,因此它必须保留所经过的所有元素。稍后,当引用被丢弃时,那些被记忆的元素也随之被丢弃(前提是,它们不是从其他对象引用的)。