Я пытаюсь создать последовательность, которая соответствует широкому поиску очень широкого, глубокого дерева ... и я сталкиваюсь с проблемами памяти, когда я слишком далеко иду по последовательности. Спросив на канале IRC и посмотрев здесь, причина № 1 в таких проблемах непреднамеренно удерживается на голове; но я не вижу, где я это делаю.Как я могу избежать нехватки памяти кучи при обработке огромных последовательностей в 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». Я запускаю их из REPL в Eclipse/CounterClockwise, на Macbook Air.
Я довольно новичок в Clojure, поэтому, после того как я избил свою голову против этого в течение дня, я надеюсь, что это что-то тривиальное, о котором я не замечаю. Я понимаю, что смогу увеличить размер кучи, чтобы сделать проблему менее вероятной, но последовательности, которые я в конечном счете хочу обработать, настолько обширны, что я не думаю, что это поможет мне.
Я попытался заменить «взять» (в приведенных выше примерах) на «падение», чтобы избежать удержания головы - это не имеет значения.
насчет вашего варианта памяти виртуальной машины Java? > = Xmx2g? –
Это поможет сделать проблему менее вероятной, но она все равно будет происходить дальше по линии, нет? –