@Michał Marczyk 的回答虽然正确,但有点难以理解。我发现this post on Google Groups 更容易掌握。
我是这样理解的:
第 1 步 创建惰性序列:(range 1e8)。值尚未实现,我将它们标记为星号(*):
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ... * * *
第 2 步再创建两个惰性序列,它们是“窗口”,您可以通过它查看原始的巨大惰性序列。第一个窗口仅包含 12 个元素 (t),其余元素 (d):
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
第 3 步 - 内存不足场景 - 您评估 [(count d) (count t)]。因此,首先计算d 中的元素,然后计算t 中的元素。将会发生的是,您将从d 的第一个元素开始遍历所有值并实现它们(标记为!):
* * * * * * * * * * * * * ! * * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
start here and move right ->
* * * * * * * * * * * * * ! ! * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
* * * * * * * * * * * * * ! ! ! * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
...
; this is theoretical end of counting process which will never happen
; because of OutOfMemoryError
* * * * * * * * * * * * * ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ... ! ! !
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
问题是所有已实现的值 (!) 都被保留,因为仍然需要集合的头部(前 12 个元素) - 我们仍然需要评估 (count t)。这会消耗大量内存导致 JVM 崩溃。
第 3 步 - 有效场景 - 这次您评估 [(count t) (count d)]。所以我们首先要计算较小的 head 序列中的元素:
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
start here and move right ->
! * * * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
然后,我们计算d 序列中的元素。编译器知道来自t 的元素不再需要,因此它可以垃圾收集它们以释放内存:
! * * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
! * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
...
... !
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
现在我们可以看到,由于不再需要来自 t 的元素,编译器能够在它通过大序列时清除内存。