This is kind of a follow-up to a question I posted last week: Simple jQuery Ajax call leaks memory in Internet Explorer
I love the jquery syntax and all of its nice features, but I've been having trouble with a page that automatically updates table cells via ajax calls leaking memory.
So I created two simple test pages for experimenting. Both pages do an ajax call every .1 seconds. After each successful ajax call, a counter is incremented and the DOM is updated. The script stops after 1000 cycles.
One uses jquery for both the ajax call and to update the DOM. The other uses the Yahoo API for the ajax and does a document.getElementById(...).innerHTML to update the DOM.
The jquery version leaks memory badly. Running in drip (on XP Home with IE7), it starts at 9MB and finishes at about 48MB, with memory growing linearly the whole time. If I comment out the line that updates the DOM, it still finishes at 32MB, suggesting that even simple DOM updates leak a significant amount of memory. The non-jquery version starts and finishes at about 9MB, regardless of whether it updates the DOM.
Does anyone have a good explanation of what is causing jquery to leak so badly? Am I missing something obvious? Is there a circular reference that I'm not aware of? Or does jquery just have some serious memory issues?
Here is the source for the leaky (jquery) version:
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('jquery', '1.4.2');
</script>
<script type="text/javascript">
var counter = 0;
leakTest();
function leakTest() {
$.ajax({ url: '/html/delme.x',
type: 'GET',
success: incrementCounter
});
}
function incrementCounter(data) {
if (counter<1000) {
counter++;
$('#counter').text(counter);
setTimeout(leakTest,100);
}
else $('#counter').text('finished.');
}
</script>
</head>
<body>
<div>Why is memory usage going up?</div>
<div id="counter"></div>
</body>
</html>
And here is the non-leaky version:
<html>
<head>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/event/event-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/connection/connection_core-min.js"></script>
<script type="text/javascript">
var counter = 0;
leakTest();
function leakTest() {
YAHOO.util.Connect.asyncRequest('GET',
'/html/delme.x',
{success:incrementCounter});
}
function incrementCounter(o) {
if (counter<1000) {
counter++;
document.getElementById('counter').innerHTML = counter;
setTimeout(leakTest,100);
}
else document.getElementById('counter').innerHTML = 'finished.'
}
</script>
</head>
<body>
<div>Memory usage is stable, right?</div>
<div id="counter"></div>
</body>
</html>
A memory leak starts when a program requests a chunk of memory from the operating system for itself and its data. As a program operates, it sometimes needs more memory and makes an additional request.
The main cause of memory leaks in an application is due to unwanted references. The garbage collector finds the memory that is no longer in use by the program and releases it back to the operating system for further allocation.
Memory is "leaking" out of the heap, never to be seen again. You allocate the memory, work with it until the program terminates. This is not a memory leak; it doesn't impair the program, and all the memory will be scavenged up automagically when the program terminates. Generally, you should avoid memory leaks.
My initial thought would be that it has something to do with the way the jquery ajax method either:
a. creates circular references, especially bad for IE
b. creates properties on internal objects which cannot be deleted due to the way they have been created and the setting of the DontDelete property. See this for more info: http://perfectionkills.com/understanding-delete/
Either way, the garbage collector would be prevented from picking up the trash, which would result in a runaway memory leak, especially if that suspect function is executing frequently.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With