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

Reply via email to