0

In my app I have a main page with some panels (DIVs) filled with AJAX calls.

HTML

<html>
<head>
    <title>jQuery test</title>
    <script type="text/javascript" src="js/jquery-1.7.1.js"></script>
    <script type="text/javascript" src="js/ago.js"></script>
</head>
<body>
    <input type="button" value="Start 1" onclick="menuAnagReferenti()"/>
    <div id="cmp-area">cmp-area</div>
</body>
</html>

ago.js

function menuAnagReferenti ()
{
    $.ajax({
        url: "./html/fromServer.html",
        cache: false,
        async: false,
        dataType: "html",
        success: function(data) {
            $('#cmp-area').empty();
            $('#cmp-area').append(data);
        }//success
    });
}//end

menuAnagReferenti() in this example is the function used to fill cmp-area panel with content get from server.

I noticed that every time I run this code (I use IE8 for the test), memory always grows. Working in this way for long time cause a performance deterioration of the whole application: after some time browser become unresponsive!

After several test, it seems that problem is in the content get from server.

This content is an HTML with some Javascript code inside most of the time.

If there is no javascript inside this HTML the memory growing does not happen!

In case HTML contains some javascript (even very short) the memory growing could still happen.

Could you help me to undestand where is the problem? Is there something wrong in my code that generate this problem?

Thanks for your helps!

Added Mar 2, 2012 --------

thanks Kevin: in my tests seems that ANY javascript generate the problem: more complex the javascript code and the memory grows more rapidly.

thanks Kory: I don't know how to use your suggestions in my case... I am using JQuery 1.7.1

1 Answers1

0

Here is answer from other thread:

I thought David might be onto something with the alleged removeChild leak, but I can't reproduce it in IE8... it may well happen in earlier browsers, but that's not what we have here. If I manually removeChild the divs there is no leak; if I alter jQuery to use outerHTML= '' (or move-to-bin followed by bin.innerHTML) instead of removeChild there is still a leak.

In a process of elimination I started hacking at bits of remove in jQuery. line 1244 in 1.3.2:

//jQuery.event.remove(this);
jQuery.removeData(this);

Commenting out that line resulted in no leak.

So, let's look at event.remove, it calls data('events') to see if there are any events attached to the element. What is data doing?

// Compute a unique ID for the element
if ( !id )
    id = elem[ expando ] = ++uuid;

Oh. So it's adding one of jQuery's uuid-to-data-lookup entry hack properties for every element it even tries to read data on, which includes every single descendent of an element you're removing! How silly. I can short-circuit that by putting this line just before it:

// Don't create ID/lookup if we're only reading non-present data
if (!id && data===undefined)
    return undefined;

which appears to fix the leak for this case in IE8. Can't guarantee it won't break something else in the maze that is jQuery, but logically it makes sense.

As far as I can work out, the leak is simply the jQuery.cache Object (which is the data store, not a really a cache as such) getting bigger and bigger as a new key is added for every removed element. Although removeData should be removing those cache entries OK, IE does not appear to recover the space when you delete a key from an Object.

(Either way, this is an example of the sort of jQuery behaviour I don't appreciate. It is doing far too much under the hood for what should be a trivially simple operation... some of which is pretty questionable stuff. The whole thing with the expando and what jQuery does to innerHTML via regex to prevent that showing as an attribute in IE is just broken and ugly. And the habit of making the getter and setter the same function is confusing and, here, results in the bug.)

[Weirdly, leaving the leaktest for extended periods of time ended up occasionally giving totally spurious errors in jquery.js before the memory actually ran out... there was something like ‘unexpected command’, and I noted a ‘nodeName is null or not an object’ at line 667, which as far as I can see shouldn't even have been run, let alone that there is a check there for nodeName being null! IE is not giving me much confidence here...]

Kory Hodgson
  • 790
  • 1
  • 5
  • 15