在Scala grouped
上调用Stream
似乎将整个流缓冲到内存中。我在这里进行了很多研究,以确定哪个类持有对Stream头的引用。
一个简单的例子:
lazy val stream1: Stream[Int] = {
def loop(v: Int): Stream[Int] = v #:: loop(v + 1)
loop(0)
}
stream1.take(1000).grouped(10).foreach(println)
如果运行此代码并在foreach
函数中放置一个断点,则可以看到在抽出Stream的头部保留了一个引用。
经过多次迭代,内存中仍然有对Stream的早期“块”的引用:
另外,如果我们检查对Stream头部的引用,则可以看到IterableLike中的某些lambda持有引用。
在grouped
上调用Stream
时,Collections库首先在iterator
上调用Stream
,返回StreamIterator
,然后返回{{1} }在那个迭代器上,返回一个GroupedIterator
。上面的屏幕快照表明grouped
中的某些内容似乎一直在Stream的头上,但我无法确定是什么。
我的问题有两个:1. Scala Streams的这种预期行为吗?如果不是,在GroupedIterator
上运行.grouped(N)
时,在StreamIterator和GroupedIterator的实现中发生什么导致流的头部被保留?