Here's a dead-simple webpage that leaks memory in IE8 using jQuery (I detect memory leaks by watching the memory usage of my iexplore.exe process grow over time in the Windows Task Manager):
<html>
<head>
<title>Test Page</title>
<script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<script type="text/javascript">
function resetContent() {
$("#content div").remove();
for(var i=0; i<10000; i++) {
$("#content").append("<div>Hello World!</div>");
}
setTimeout(resetTable, 2000);
}
$(resetContent);
</script>
<div id="content"></div>
</body>
</html>
Apparently even when calling the jQuery.remove()
function I still experience some memory leakage. I can write my own remove function that experiences no memory leak as follows:
$.fn.removeWithoutLeaking = function() {
this.each(function(i,e){
if( e.parentNode )
e.parentNode.removeChild(e);
});
};
This works just fine and doesn't leak any memory. So why does jQuery leak memory? I created another remove function based on jQuery.remove()
and this does indeed cause a leak:
$.fn.removeWithLeakage = function() {
this.each(function(i,e) {
$("*", e).add([e]).each(function(){
$.event.remove(this);
$.removeData(this);
});
if (e.parentNode)
e.parentNode.removeChild(e);
});
};
Interestingly, the memory leak seems to be caused by the each call which jQuery includes to prevent memory leaks from events and data associated with the DOM elements being deleted. When I call the removeWithoutLeaking
function then my memory stays constant over time, but when I call removeWithLeakage
instead then it just keeps growing.
My question is, what about that each call
$("*", e).add([e]).each(function(){
$.event.remove(this);
$.removeData(this);
});
could possibly be causing the memory leak?
EDIT: Fixed typo in code which, upon retesting, proved to have no effect on the results.
FURTHER EDIT: I have filed a bug report with the jQuery project, since this does seem to be a jQuery bug: http://dev.jquery.com/ticket/5285