2016-05-23 1 views
2

У меня есть XML-файл размером 700 мб, который я обрабатываю из дерева записей в файл EDN.Clojure: почему этот писатель потребляет столько кучи пространства?

После выполнения всей обработки я, наконец, имею ленивую последовательность хешмапов, которые не особенно большие (не более 10 значений).

Чтобы закончить, я хочу, чтобы записать его в файл с

(defn write-catalog [catalog-edn] 
    (with-open [wrtr (io/writer "catalog-fr.edn")] 
    (doseq [x catalog-edn] 
     (.write wrtr (prn-str x))))) 

Я не понимаю эту проблему, потому что doseq предполагается не удерживать голову последовательности в памяти.

Мой конечный результат catalog имеет тип clojure.lang.LazySeq.

Я тогда делать

(write-catalog catalog) 

Затем использование памяти шлифовке и у меня есть ошибка GC над головой около 80 МБ файла writter с XMX из 3g.

Я также пробовал с doseq + spit и не prn-str, то же самое бывает.

Это нормальное поведение?

Благодаря

ответ

2

Возможна утечка памяти из-за реализации catalog значений (Google "удержание головы"). Когда ваш write-catalog реализует предметы один за другим, они хранятся в памяти (очевидно, вы где-то находитесь def 'fing catalog). Чтобы исправить это, вы можете попытаться избежать сохранения своего каталога в переменной, а затем передать его на write-catalog сразу. Как если бы вы разобрать его откуда-то (что я предполагаю, что это правда, учитывая предыдущий вопрос), вы хотели бы сделать:

(write-catalog (transform-catalog (get-catalog "mycatalog.xml")))

так огромные промежуточные последовательности не будут есть всю память

Надеюсь, поможет.

+1

Вы правы, я забыл, что заметил это. Если я хорошо понимаю, сборщик мусора не может освободить seq до тех пор, пока определено ограничение var. Я потребляю сейчас не так много памяти. Благодаря !! –

Смежные вопросы