In this SO thread, habe ich gelernt, dass ein Verweis auf eine seq
auf einer großen Sammlung verhindern wird, dass die gesamte Sammlung von Müll gesammelt wird.Wann sollte ich `seq` in Clojure vermeiden?
Erstens, dieser Thread ist von 2009. Ist dies immer noch in "modernen" Clojure (v1.4.0 oder v1.5.0) wahr?
Zweitens, gilt dieses Problem auch für Lazy-Sequenzen? Zum Beispiel würde (def s (drop 999 (seq (range 1000))))
dem Garbage Collector ermöglichen, die ersten 999
Elemente der Sequenz zu beenden?
Schließlich gibt es eine gute Möglichkeit, dieses Problem für große Sammlungen zu umgehen? Mit anderen Worten, wenn ich einen Vektor von, sagen wir, 10 Millionen Elementen hätte, könnte ich den Vektor so konsumieren, dass die verbrauchten Teile Müll gesammelt werden könnten? Was wäre, wenn ich eine Hashmaps mit 10 Millionen Elementen hätte?
Der Grund, warum ich frage, ist, dass ich auf ziemlich großen Datensätzen arbeite, und ich muss vorsichtiger sein, Verweise auf Objekte nicht zu behalten, so dass die Objekte, die ich nicht brauche, Müll gesammelt werden können. Wie es ist, stoße ich in einigen Fällen auf einen java.lang.OutOfMemoryError: GC overhead limit exceeded
Fehler.
Ich denke @Cgrands Beispiel '(fallen 999990 (vec (Bereich 1000000))) ist aufgrund der intervenierenden Vektor und das Verhalten von' subvec'toring. Ich vermute nicht, dass eine faule "cons" Sequenz dies tun würde. Wenn Sie einen Vektor freigeben müssen, während Sie einen Subvektor beibehalten, können Sie den Subvektor in einen neuen Vektor kopieren. Sehr interessante Frage, ich warte darauf, die Antworten zu sehen! –