2016-05-23 13 views
2

Ich habe eine 700 MB XML-Datei, die ich von einem Datensatzbaum zu einer EDN-Datei verarbeiten.Clojure: Warum verbraucht dieser Schreiber so viel Heap-Speicherplatz?

Nachdem ich die ganze Verarbeitung gemacht habe, habe ich endlich eine faule Folge von Hashmaps, die nicht besonders groß sind (höchstens 10 Werte).

Zum Abschluss möchte ich

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

verstehe ich nicht das Problem mit ihm in eine Datei schreiben, weil doseq soll den Kopf der Sequenz im Speicher nicht behalten zu tun.

Mein endgültiger Ausgang catalog ist vom Typ clojure.lang.LazySeq.

ich dann

(write-catalog catalog) 

Dann Speichernutzung ist das Schleifen und ich habe einen GC-Overhead Fehler bei etwa 80 MB Datei writter mit einem XmX von 3g.

Ich versuchte auch mit einer doseq + spit und keine prn-str, gleiche Sache passieren.

Ist das ein normales Verhalten?

Dank

Antwort

2

Möglicherweise sind die Speicherverluste aufgrund der catalog Werte Realisierung (google "Kopf retention"). Wenn Ihre write-catalog Elemente nacheinander ausführt, werden sie im Speicher gehalten (offensichtlich sind Sie irgendwo def 'fing catalog). Um dies zu beheben, sollten Sie versuchen, Ihren Katalog nicht in einer Variablen zu belassen, sondern ihn stattdessen an die write-catalog übergeben. Wie, wenn Sie es von irgendwo analysieren (was ich denke, wahr ist, Ihre vorherige Frage bedenkt), möchten Sie tun wollen:

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

so großen Zwischensequenzen werden nicht alle Speicher essen

Ich hoffe es hilft.

+1

Sie haben Recht, ich habe vergessen, dass ich das bemerkt habe. Wenn ich es gut verstehe, kann der Garbage Collector die Seq nicht freigeben, solange die definierte Variable gebunden ist. Ich konsumiere jetzt nicht viel Speicher. Vielen Dank !! –

Verwandte Themen