Le 01/11/2013 21:13, Andrew McCreight a écrit :
----- Original Message -----
Why so?

      function f(e){}

      (function(){
          var iframe = document.getElementByTagName('iframe')[0];
          iframe.addEventListener('someEvent', f);
      })()

In this case, f doesn't hold a reference to anything besides itself, not
to the iframe at least. In the case of DOM events, it can look at its
argument to find e.target which will dynamically (!), only for the time
of the listener call, refer to the iframe.

In any case, when an event doesn't need to be listened to anymore, there
is a time in your application where you can remove the listener. The
leak is not removing the listener, not the listener itself.
Well, you can look at the patch.  I guess I described it poorly.  You have some 
thing (I said 'iframe' above, but I guess it isn't really one) x that wants to 
listen to an event, so you create an event listener for it, that holds alive x. 
 The situation is more like this:

       function f(e){tellSomebodyAboutTheEvent(x);}

       (function(){
           var iframe = document.getElementByTagName('iframe')[0];
           iframe.addEventListener('someEvent', f);
       })()

f is now keeping x alive, and if f is the only thing keeping x alive, then 
that's basically a leak as far as we are concerned as a JS programmer.
There is a point in your program in which you know that 'iframe' won't be needed anymore and you do something about that. Maybe you clear a given data structure, maybe you remove the iframe from the document without assigning it to a variable, maybe you do something else, but you do do something. It's at this point that either you want to remove the listener or reassign x to another value.

(There's also the problem that f stays alive forever if the event never fires, 
but that's a smaller leak...)
It's only a leak if you *know* that the event will never fire. If the event may never fire, that's not a leak, just bad luck.

In case being concrete helps
(it does :-) )

in our case, x was the parent-process representation of some app, and the event 
was some kind of visibility change event, so you can tell the app if the screen 
is turned off or on.  Obviously, you want to get rid of x rather than keep it 
around to ensure that we can tell this zombie app thing that the screen is 
going to turn off.
Ok. I think I understand better the patch now. Thanks.
I noticed a bug in the patch [1]. It's been interestingly fixed as a side-effect of bug 899354 [2], but sharing for those interested. In the patch [1], the event listener is visibilityChangeHandler.bind(/*args*/). The listener that is attempted to be removed is visibilityChangeHandler which is a different function and was never itself registered as a listener, so the listener was never removed and the removeEventListener call failed silently.

Even with the new version, as application author, you know when you don't want a given browserElementParent (x) any longer, so you know when to break all the references. The only thing that's lacking is API bits all over the place for you to break these references. It's more work than weak references, but it's doable.

David

[1] https://hg.mozilla.org/mozilla-central/rev/d23e2b6fb808
[2] https://hg.mozilla.org/mozilla-central/rev/602e8b21a0ff
_______________________________________________
dev-tech-js-engine-internals mailing list
dev-tech-js-engine-internals@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals

Reply via email to