5 ms·
The OP is confused --- a proper garbage collector will collect cyclic structures. The situation that he describes was a problem in versions of IE prior to ie8
by rst 15y ago
The OP is confused --- a proper garbage collector will collect cyclic structures.
The situation that he describes was a problem in versions of IE prior to ie8 because of limitations on its garbage collector --- specifically that it was unable to collect cycles if the cycle involved a DOM element. This is fixed in ie8 (and, presumably, subsequent versions), and even in ie7 the situation gets cleaned up when the user navigates away from the page (although JS that creates a lot of "throwaway" DOM elements could still get into trouble). So, most programmers really have to worry about this only if still targeting ie6.
(By the way, if you are afflicted with ie6, the jQuery 'data' APIs work around this misbehavior; other libraries often have similar tricks.)
The official scoop from Microsoft: http://msdn.microsoft.com/en-us/library/dd361842%28v=vs.85%29.aspx http://msdn.microsoft.com/en-us/library/dd361842%28v=vs.85%2...
- victorNicollet 15y agoIndeed. Last I checked, jQuery breaks the cycle when elements are removed from the DOM by going through all their event handlers and data members and dropping them.
- bentruyman 15y agoI don't think jQuery is necessarily relevant in this discussion. This post is talking about JavaScript closures in general, regardless of whether or not it's DOM events or plain old callbacks.
- spjwebster 15y agoIndeed. Also, a slightly more succinct fix for IE6/7 would be: function foo(element, a, b) { element.onclick = function() { /* uses a and b */ }; element = null; // avoid memory leak } The closure contains a reference to foo's activation object, not to its properties. As a consequence, you can clear out the element reference after the event handler has been defined and this will break the circular reference. The above technique is also useful when creating anonymous functions for other purposes when element references happen to be lying around. Depending on how long these anonymous functions are kept alive and what you do with the elements in the meantime, this would normally lead to a memory leak (due to the dangling reference to the DOM element, rather than a circular reference as described in the article). See http://jibbering.com/faq/notes/closures/ http://jibbering.com/faq/notes/closures/ for a seriously nerdy deep-dive into closures in JavaScript.
- pbiggar 15y ago(Edit: I think I'm wrong here. It does indeed look like the OP is saying that the DOM node would leak after the cycle has no incoming pointers. I read it to say that other objects in the closed-over scope would be leaked as long as the reference was live). I don't think the OP is confused. Nothing he has said is inaccurate, and you're asserting something he didn't say. > A proper garbage collector will collect cyclic structures. Absolutely true, so long as they are garbage. However, nothing the OP says implies that the DOM node is garbage. As I read it, the leak comes from accidentally extending the life of the enclosing scope to the life of the DOM node. That's a real leak (in the web app, not in the browser).
- spjwebster 15y agoIn every browser except IE4-7, removing the DOM node from the document would result in the entire lot getting garbage collected. This is garbage collection collecting garbage. However, in IE4-7 the JS garbage collector isn't responsible for handling DOM nodes and vice versa. Consequently, this results in a memory leak; in IE 4-6 this persists until the browser terminates, and in IE7 it persists until the user navigates to another page. There is a related application-level memory leak if you have some other reference to the closure that doesn't belong to the DOM node, and that applies to all browsers. See http://news.ycombinator.com/item?id=2567847 http://news.ycombinator.com/item?id=2567847 for a simple way to deal with that.