views:

397

answers:

3

I'm running this script in Google Chrome while using the Chrome Task Manager to monitor memory usage:

<html>
<head>
    <title>Test Page</title>
    <script type="text/javascript" src="jquery-1.3.2.js"></script>
    <script type="text/javascript">

        var count = 0;

        function incrementContent() {
            $("#content").text(count);
            count++;
            setTimeout(incrementContent, 5);
        }

    </script>
</head>
<body onload="incrementContent()">
<div id="content">
</div>
</body>
</html>

Memory usage will steadily increase to a maximum of ~31,000K, it then stays at this level.

As far as I can see the loop should simply overwrite the same element in the document.

What is causing the large amount of memory to be allocated?

Using IE 8 I can see no no discernible increase in memory usage while running the script.

With Firefox 3.5.3 memory usage goes through a cycle of increasing by a few megabytes over a minute or so and then falling back its baseline level.

+1  A: 

You're recursively calling setTimeout. Don't do this. Since there is no base case to stop the recursive call, it will continue indefinitely.

In a language like Java, this would eventually cause a StackOverflowException. I'm not sure what Javascript does, aside from eat memory.

Instead, use setInterval:

function incrementContent() {
    $("#content").text(count);
    count++;
}
setInterval(incrementContent, 5);
Matt Ball
I don't think the example demonstrates classical recursion - the method does not call itself directly. Instead it sets an event to call it self again in the future before it exits.I thought that as the method does exit, the reference to it would get popped off the stack and hence there couldn't be a StackOverflowException?
I still see exactly the same behaviour when I use setinterval as Matt suggests.My theory is that jQuery must be storing something when the content of the div is changed. But what and why?
Honestly, I don't know enough about the underlying implementation of setTimeout and setInterval (aside from the fact that they're really sketchy). I did just notice that you said memory usage increases to ~31,000K "before stopping." First, that's only 31mb, which isn't much at all, and second, by "before stopping" do you mean "before the browser hangs," or "before memory usage stops increasing?"
Matt Ball
Sorry, I meant that memory usage stops increasing - I'll edit the question.
`setTimeout` is a method on `window`. The code is an infinite loop by design but it's not infinite recursion; there's only one `incrementContent` on the stack at any given time.
hobbs
+2  A: 

Have you established a baseline for Chrome's memory usage without jQuery? If you suspect jQuery then implement your sample without jQuery and see how the memory usage goes.

Also I notice you are using a locally hosted copy of jQuery in your script. Have you considered pulling the library from a free CDN? Google's AJAX CDN Microsoft's AJAX CDN

Andrew
Good idea - I tested another script that used getElementById and innerHTML to change the content div. This results in ~7,000K of memory being allocated. The level of memory used stays constant.
Thanks for the tip about the free CDNs. I can see how they would be useful.
It would seem that jQuery is at fault then. I didn't think setTimeout or setInterval would be the problem.I made this change to the code:if (count <= 20000) {setTimeout(incrementContent, 5)};and found that after the code stops running the memory usage drops back. I suspect that what is happening is that the code is outrunning the garbage collector, there is no leak.
Andrew
That seems a reasonable explanation to me
A: 

hi,

im experiencing the same problem too. my code is slightly different.

kInterval = setInterval("startK()",3000);

function startK() { // send to debug debug("it works"); }

suddenly the chrome stops the loop at 25 MB. wonder if there is a limitation to number of loops in chrome.

remi
In my example the loop didn't stop - it would have continued running indefinately. Are you saying that your program crashes when memory usage hits 25MB?