使用seque函数时的OutOfMemoryError

时间:2014-03-01 21:20:40

标签: clojure

我有这个功能可以重现我的问题:

(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(在本例中)。我不明白内存泄漏的位置。

1 个答案:

答案 0 :(得分:6)

实现seque的方式,如果消耗的元素比生成元素的速度快得多,那么大量代理任务将堆积在seque内部使用的队列中(最多一个)序列中每个元素的任务)。从理论上讲,你所做的应该是好的,但在实践中它并没有真正成功。您应该只需运行(dorun (seque (range)))即可看到相同的效果。

您还可以使用flatland/useful中的sequeue函数,该函数的权衡与clojure.core中的权衡不同。仔细阅读文档字符串,但我认为它适用于您的情况。