On Aug 9, 2:40 am, RobG <rg....RemoveThis@iinet.net.au> wrote:
> On Aug 9, 2:22 pm, David Mark <dmark.cins....RemoveThis@gmail.com> wrote:
>
>
>
>
>
> > On Aug 8, 11:38 pm, RobG <rg....RemoveThis@iinet.net.au> wrote:
>
> > > On Aug 9, 1:07 pm, David Mark <dmark.cins....RemoveThis@gmail.com> wrote:
>
> > > > On Aug 8, 10:21 pm, RobG <rg....RemoveThis@iinet.net.au> wrote:
> > > > > On Aug 9, 10:37 am, David Mark <dmark.cins....RemoveThis@gmail.com> wrote:
>
> > [snip]
>
> > > > No. I didn't catch that specific problem. Setting the variables to
> > > > null won't help that?
>
> > > The closure involves the activation object of the outer function
> > > itself, only way to break it is to remove the handler, say by setting
> > > it to null when the unload event occurs:
>
> > I do that when I am aware of creating circular references. In this
> > case, I see the circular reference, but can't understand why setting
> > the variable referencing the created element to null wouldn't break
> > the cycle.
>
> Given:
>
> function addClick(id){
> var domNode = document.getElementById(id);
> domNode.onclick = function(){...};
>
> // Break circular reference
> domNode = null;
>
> }
>
> Without that last statement, we have Richard's example:
>
> "DOM_Node.onevent -> function_object.[[scope]] ->
> scope_chain -> Activation_object.nodeRef -> DOM_Node"
>
> Setting domNode to null inside the function removes the circular
> reference, the chain is broken and as far as I can tell, you are
> right: there is no leak (I've done a few tests that seem to confirm
> it).
Glad to hear it.
>
> That seems to agree with Douglas Crockford's article[1] on memory
> leaks where he points out that circular references are the issue, not
> closures. I also went back and did a search on Richard Cornford's
> posts to clj and he says the same thing (repeatedly, actually
) - I
> guess I was blind-sided by the association with closures.
You probably saw the one where I raised the same issue about
associating DOM events with object method. As long as the object
doesn't hold a reference to the element, it doesn't require cleanup.
>
> Re-reading Richard's article I can see now what he was getting at:
> when using closures and event handlers, it is common to create
> circular references and leave them hanging around. Perhaps in the
> conclusion about memory leaks he could include a something about
> removing them by setting references to null where possible in addition
> to the current advice about removing the handlers onunload.
I think that would make sense.
>
> > > <URL:http://www.jibbering.com/faq/faq_notes/closures.html#clMem>
>
> > > > If not, I guess the only way to avoid that type
> > > > of leak is to reference an existing function. (?)
>
> > > Avoidance is always best, you can use references or if you want to
> > > pass parameters, use the Function constructor:
>
> > > var foo = 'bar';
> > > tdGrid.onmouseover = Function('alert("foo is ' + foo + '")');
>
> > > which is not favoured by some. An alternative is cleaning up
>
> > I know JSLint doesn't like it. But then it doesn't like
> > document.write for the same reason (it claims they "might" be eval's.)
>
> Some have said that it is unreasonable for JSLint to complain about
> using the Function constructor for its intended purpose: constructing
> functions. Some mumble about "nearly as bad as eval", which I take to
> mean "have you thought about this thoroughly" and "aren't there less
> resource intensive and more elegant methods available" - I guess
> that's what JSLint is hinting at.
That's what I figured. I stopped using the Function constructor once
I discovered closures.
>
> > > afterward, though it requires a bit more effort to design properly
> > > (frameworks for adding, remembering and removing handlers are
> > > reasonably common, there are a few in the archives here and in many
> > > script libraries).
>
> > I have my own, but only push methods onto the cleanup stack if I know
> > they create circular references (eg associating a DOM element's events
> > with methods of an object that holds a reference to the element.)
>
> There is always the generic "cycle over all DOM elements and set any
> property whose typeof == function to null" quick-fix.
I don't care for catch-alls as they seem like assertions that the
author didn't understand what the script did (usually a bad sign.)