On Wed, Aug 11, 2010 at 1:25 AM, timcharper <timchar...@gmail.com> wrote: > > I've distilled the issue down to a series of two tests: in one case, > the head is properly released, and in the other, the head is retained > even though it seems it shouldn't be. > > http://gist.github.com/510601
Those are nice tests. Please excuse my poorer ones below... ...but I think this isn't specifically about lazy seqs or futures, though those clearly are affected. It's actually about gc and closures. Let's start with a helper function that retains a reference to a closure while trying to GC a possibly related object: (defn attempt-gc [closure weak-ref n] (loop [i 0] (System/gc) (when (and (< i n) (.get weak-ref)) (Thread/sleep 1000) (recur (inc i)))) closure) Now if we call this with a closure that does *not* close over the object the weak-ref refers to, the object gets GC'ed promptly and control returns immediately: (let [x (Object.), r (java.lang.ref.WeakReference. x)] (attempt-gc #(do nil) r 5)) Note that the Clojure compiler's local-clearing is helping us here -- it's noticing nothing in the body of the let needs x, so it's getting cleared and GC'ed before the attempt-gc loop has to run more than once. But if the closure *does* close over the object, the closure itself retains a reference to it and local-clearing in the 'let' doesn't help. So attempt-gc tries for several seconds before giving up: (let [x (Object.), r (java.lang.ref.WeakReference. x)] (attempt-gc #(do x nil) r 5)) It's not clear to me whether or not the Compiler could do something about this. Note there's no lazy seq or future (or indeed thread boundaries of any kind) in either of my examples, though of course retaining the head of a lazy seq retains the entire seq, and creating a future does create a closure. --Chouser http://joyofclojure.com/ -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en