I am working on a large enterprise application with a LOT of JavaScript. Enough that I can\'t possibly go through and fix all the small circular references that have been create
I'm going to theorise that it's similar to .net garbage collection, in that it relies on Pinned objects in the heap.
IE is treating the parent of a removed object like a pin and not clearing the removed object down properly.
The act of moving the deleted item to this generated gc container is basically removing the pin because IE knows that nothing is relying on that container.
That's my gut feeling anyway.
This is the .remove
method in the current jQuery release (1.6.2). Notice that it calls .cleanData
:
// keepData is for internal use only--do not document
remove: function( selector, keepData ) {
for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
if ( !keepData && elem.nodeType === 1 ) {
jQuery.cleanData( elem.getElementsByTagName("*") );
jQuery.cleanData( [ elem ] );
}
if ( elem.parentNode ) {
elem.parentNode.removeChild( elem );
}
}
}
return this;
},
And the .cleanData
method which it calls, which mentions a ticket number and allegedly prevents that horrible leak (according to one of the comments):
cleanData: function( elems ) {
var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
deleteExpando = jQuery.support.deleteExpando;
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
continue;
}
id = elem[ jQuery.expando ];
if ( id ) {
data = cache[ id ] && cache[ id ][ internalKey ];
if ( data && data.events ) {
for ( var type in data.events ) {
if ( special[ type ] ) {
jQuery.event.remove( elem, type );
// This is a shortcut to avoid jQuery.event.remove's overhead
} else {
jQuery.removeEvent( elem, type, data.handle );
}
}
// Null the DOM reference to avoid IE6/7/8 leak (#7054)
if ( data.handle ) {
data.handle.elem = null;
}
}
if ( deleteExpando ) {
delete elem[ jQuery.expando ];
} else if ( elem.removeAttribute ) {
elem.removeAttribute( jQuery.expando );
}
delete cache[ id ];
}
}
}
And here is the ticket mentioned in the comment. Apparently it was fixed eight months ago:
http://bugs.jquery.com/ticket/7054#comment:10
According to Dave Methvin the solution seems to be to Ensure that the DOM element ref in an event handler is removed by cleanData to avoid an IE6/7/8 memory leak.
In other words, set references to DOM elements within event handlers to null
otherwise some awesome browsers, without mentioning any names cough IE cough will leak memory.
discardElement
(from your link) inserts the element into a container, and then empties the container, thereby nullifying any references to that element.
With that in mind, I would suggest upgrading jQuery. The article you point to is from 2009, and two years is roughly equivalent to four-hundred-zillion man hours of jQuery development time.
Finally, here is some interesting (and ridiculously long) reading on leak patterns in Internet Explorer: