On Tue, Nov 10, 2009 at 7:21 AM, Rich Hickey <richhic...@gmail.com> wrote:

> Right - pervasive locals clearing will definitely do the trick here.
> Interestingly, when I was at Microsoft and asked them about handling
> this issue for the CLR they stated plainly it wasn't an issue at all -
> their system can fully detect that any such references are in fact
> unreachable and are subject to GC. So, in a sense, all locals clearing
> on my part is a workaround for a JVM weakness in this area.


Did you see my earlier post? One possible workaround in this specific
instance could be to use SoftReference to make a "clearable" local in the
let outside the loop. In case of any worries about the reference being
cleared in the few nanos before it can be copied into the loop variables,
you could also use a mutable store, e.g.

let [G__13697 (atom s)
      [x & xs] @G__13697
      x (atom x)
      xs (atom xs)
      y (atom @xs)
      grab (fn [a] (let [x @a] (reset! a nil) x))]
  (loop* [G__13697 (grab G__13697)
          y (grab y)]
         (let [[x & xs] G__13697
               y y]
           ...)))

How it works:
1. When the outer let is needed due to destructuring, the nondestructuring
binds are wrapped in (atom). The destructuring binds are not, but each
destructuring-produced binding is then rebound to itself wrapped in (atom).
Any reference to one of the preceding locals is wrapped in (deref).
2. When the loop needs to initialize its loop variables, it wraps access to
the let's variables in grab, which returns the contents of the atom while
also resetting it.

It's not very CPU efficient, since it uses atoms which seem to be slow, but
it will prevent head-retention of lazy seqs IF (let [x the-seq x
something-else]) lets go of the head of the-seq when the second binding of x
in the same let is performed.

By the time the loop body begins executing, the only things the outer let's
bindings are holding onto will be tiny little empty atoms, consuming just a
few heap bytes each.

-- 
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