W książce this SO thread dowiedziałem się, że zachowanie odniesienia do zbioru seq
w dużej kolekcji uniemożliwi zbieranie całej kolekcji.Kiedy należy unikać używania `seq` w Clojure?
Po pierwsze, ten wątek pochodzi z 2009 r. Czy jest to nadal prawdziwe w "nowoczesnym" Clojure (v1.4.0 lub v1.5.0)?
Po drugie, czy ten problem dotyczy również leniwych sekwencji? Na przykład, czy (def s (drop 999 (seq (range 1000))))
zezwala odśmiecnikowi na wycofanie pierwszych elementów sekwencji? 999
?
Wreszcie, czy istnieje dobry sposób obejścia tego problemu w przypadku dużych kolekcji? Innymi słowy, gdybym miał wektor, powiedzmy 10 milionów elementów, mógłbym konsumować wektor w taki sposób, aby zużyte części mogły być zebrane? A co, jeśli miałbym mieszankę z 10 milionami elementów?
Powodem, dla którego pytam, jest to, że operuję na dość dużych zbiorach danych, i muszę być bardziej ostrożny, aby nie przechowywać odniesień do obiektów, tak że obiekty, których nie potrzebuję, mogą być śmieciami zebranymi. W niektórych przypadkach napotykam błąd java.lang.OutOfMemoryError: GC overhead limit exceeded
.
Myślę, że przykład @ cgrand '(drop 999990 (vec (range 1000000))) jest spowodowany interweniującym wektorem i zachowaniem' subvec'toring. Nie podejrzewam, że zrobiłaby to leniwy sekwencja "cons". Jeśli chcesz zwolnić wektor zachowując subwektor, możesz skopiować subwektor "do" nowego wektora. Bardzo ciekawe pytanie, czekam też na odpowiedzi! –