在一个简单的懒惰seq上的doseq用完了堆空间

时间:2012-08-13 10:55:15

标签: clojure lazy-sequences

在对某些Clojure代码进行压力测试时,我发现在迭代大型数据集时,它会耗尽堆空间。我最终设法将问题追溯到Clojure的doseq函数和懒惰序列的实现组合。

这是通过耗尽可用堆空间来崩溃Clojure的最小代码段:

(doseq [e (take 1000000000 (iterate inc 1))] (identity e))

doseq的文档明确指出它不会保留延迟序列的头部,所以我希望上面代码的内存复杂性接近于O(1)。有什么我想念的吗?如果doseq无法完成工作,那么迭代非常大的惰性序列的Clojure惯用方法是什么?

1 个答案:

答案 0 :(得分:2)

当我运行这个示例时,我看到内存使用量达到2.0 Gigs,所以也许你实际上只是用完ram了。

确实需要一段时间才能运行:

user=> (time (doseq [e (take 1000000000 (iterate inc 1))] (identity e)))
"Elapsed time: 266396.221132 msecs"

表格顶部:

23999 arthur    20   0 4001m 1.2g 5932 S  213 15.3  17:11.35 java                                          
24017 arthur    20   0 3721m 740m 5548 S   88  9.3  13:49.95 java