Вызов grouped
в Scala 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
функция, можно видеть, что ссылка удерживается на голове потока, когда он вытягивается.
После нескольких итераций в памяти все еще остаются ссылки на более ранние "куски" потока:
Кроме того, если мы проверим ссылку на начало потока, мы увидим, что некоторая лямбда в IterableLike содержит ссылку.
Когда grouped
вызывается на Stream
, библиотека Коллекций сначала вызывает iterator
на Stream
, возвращая StreamIterator
а затем grouped
на этого итератора , возвращающего GroupedIterator
.Снимки экрана выше предполагают, что что-то в GroupedIterator
, кажется, удерживает голову потока, но я не могу определить что.
Мой вопрос состоит из двух частей: 1. Это ожидаемое поведение в Scala Streams?Если нет, что произошло в реализации StreamIterator и GroupedIterator, чтобы удержать заголовок потока при выполнении .grouped(N)
на Stream
?