Scala 使用toStream时,中间列表是否有资格进行垃圾收集?
假设我想创建一个Scala 使用toStream时,中间列表是否有资格进行垃圾收集?,scala,stream,garbage-collection,Scala,Stream,Garbage Collection,假设我想创建一个列表[(Int,Int)]: 但是,如果我想创建一个流[(Int,Int)]呢 scala> (0 to 3).toList.zip(0 to 3).toStream res4: scala.collection.immutable.Stream[(Int, Int)] = Stream((0,0), ?) 是用于构建垃圾回收的 RES4的中间列表吗?< /P> < P>如果将列表作为包含列表的头+链接到尾部的对象,答案是肯定的。 根据消息来源,在创建的流中并没有输入列表
列表[(Int,Int)]
:
但是,如果我想创建一个流[(Int,Int)]
呢
scala> (0 to 3).toList.zip(0 to 3).toStream
res4: scala.collection.immutable.Stream[(Int, Int)] = Stream((0,0), ?)
是用于构建垃圾回收的<代码> RES4的中间列表吗?< /P> < P>如果将列表作为包含列表的头+链接到尾部的对象,答案是肯定的。 根据消息来源,在创建的流中并没有输入列表的闭包,所以可以收集这个列表(实际上只是“:“case class”)。但列表的尾部(剩余的“:””链)在闭包(var-tlGen)中被捕获,直到您在流上迭代为止
override def toStream : Stream[A] =
if (isEmpty) Stream.Empty
else new Stream.Cons(head, tail.toStream)
final class Cons[+A](hd: A, tl: => Stream[A]) extends Stream[A] {
override def isEmpty = false
override def head = hd
@volatile private[this] var tlVal: Stream[A] = _
@volatile private[this] var tlGen = tl _
def tailDefined: Boolean = tlGen eq null
override def tail: Stream[A] = {
if (!tailDefined)
synchronized {
if (!tailDefined) {
tlVal = tlGen()
tlGen = null
}
}
tlVal
}
}
所以,当流完全迭代时,所有尾部都有资格收集
例如,让我们以List(1,2,3,4).toStream.foreach(=>{})为例:
为什么不从一个流而不是一个列表开始:
(0到3).toStream.zip((0到3))
我认为在实际情况下,第一个或第二个集合并没有生成-所以我们仍然有问题List.toStream或Stream.zip(\uz:List)。无论如何,集合的尾部(无论其实现如何)将被捕获,直到流被迭代(参见我的答案)。
override def toStream : Stream[A] =
if (isEmpty) Stream.Empty
else new Stream.Cons(head, tail.toStream)
final class Cons[+A](hd: A, tl: => Stream[A]) extends Stream[A] {
override def isEmpty = false
override def head = hd
@volatile private[this] var tlVal: Stream[A] = _
@volatile private[this] var tlGen = tl _
def tailDefined: Boolean = tlGen eq null
override def tail: Stream[A] = {
if (!tailDefined)
synchronized {
if (!tailDefined) {
tlVal = tlGen()
tlGen = null
}
}
tlVal
}
}
stream iteration captured tail generated stream eligible for GC
0 List(2, 3, 4) Stream(1, ?) List(1, 2, 3, 4)
1 List(3, 4) Stream(1, 2, ?) List(2, 3, 4)
2 List(4) Stream(1, 2, 3, ?) List(3, 4)
3 Nil Stream(1, 2, 3, 4) List(4)