我試圖生成一個序列,它對應於廣泛深度樹的廣度優先搜索......當我沿着序列走得太遠時,我遇到了內存問題。在問及IRC頻道並看了這裏之後,導致這些問題的頭號原因是無意中捂住了腦袋;但我看不到我在做什麼。在Clojure中處理大量序列時,如何避免用盡堆內存?
該代碼非常簡單;這裏是其中顯示了問題的一個版本:
(def atoms '(a b c))
(defn get-ch [n] (map #(str n %) atoms))
(defn add-ch
([] (apply concat (iterate add-ch atoms)))
([n] (mapcat get-ch n)))
(dorun (take 20000000 (add-ch)))
而這裏的另一個版本(這是我正從#clojure幫助之前,開始了以一個),它顯示了同樣的問題:
(def atoms '(a b c))
(defn get-children [n] (map #(str n %) atoms))
(defn add-layer
([] (add-layer atoms))
([n] (let [child-nodes (mapcat get-children n) ]
(lazy-seq (concat n (add-layer child-nodes))))))
(dorun (take 20000000 (add-layer)))
兩個給我一個「OutOfMemoryError Java堆空間」。我使用Eclipse/CounterClockwise中的REPL在Macbook Air上運行它們。
我對Clojure非常陌生,所以在打了一天我的頭後,我希望這是我忽略的一些小事。我意識到我可以提高堆大小以減少問題的發生,但是我最終想要處理的序列非常龐大,我認爲這不會對我有幫助。
我試過用「drop」替換「take」(在上面的例子中),以避免保持頭部 - 它沒有區別。
那你的JVM的內存選項? > = Xmx2g? –
這有助於減少問題發生的可能性,但它仍然會發生在更遠的地方,不是嗎? –