运行此代码最终会抛出OOME
`
(let [c (a/chan)]
(a/go (while (a/<! c)))
(a/go
(when-some [xs (range)]
(doseq [x xs]
(a/>! c x)))))
`
这个(用{{let}}而不是{{when-some}})可以正常工作
`
(let [c (a/chan)]
(a/go (while (a/<! c)))
(a/go
(let [xs (range)]
(doseq [x xs]
(a/>! c x)))))
`
在前一个例子中,range序列存储在堆上(在go块的状态数组中),并且在doseq迭代期间一直保留,尽管在循环初始化后不再需要。
在后者中,range序列存储在栈上,因此编译器能够执行其局部清理魔术。
这种行为很可能会发生在每个跨越多个SSA块的值上。