我有这个功能可以重现我的问题:
(defn my-problem
[preprocess count print-freq]
(doseq [x (preprocess (range 0 count))]
(when (= 0 (mod x print-freq))
(println x))))
当我用这样的身份函数调用它时,一切正常:
(my-problem identity 10000000 200000)
;it prints 200000,400000 ... 9800000 just as it should
当我用seque函数调用它时,我得到OutOfMemoryError:
(my-problem #(seque 5 %) 10000000 200000)
;it prints numbers up to 2000000 and then it throws OutOfMemoryException
我的理解是seque函数应该使用ConcurrentBlockingQueue将处理分成两个线程,最大大小为5(在本例中)。我不明白内存泄漏的位置。
答案 0 :(得分:6)
实现seque
的方式,如果消耗的元素比生成元素的速度快得多,那么大量代理任务将堆积在seque
内部使用的队列中(最多一个)序列中每个元素的任务)。从理论上讲,你所做的应该是好的,但在实践中它并没有真正成功。您应该只需运行(dorun (seque (range)))
即可看到相同的效果。
您还可以使用flatland/useful中的sequeue
函数,该函数的权衡与clojure.core中的权衡不同。仔细阅读文档字符串,但我认为它适用于您的情况。