Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
318 views
in Technique[技术] by (71.8m points)

javascript - jQuery load() method memory leak?

I have hunted around for answer to this one, and though have found related quesions, I couldn't quite find an exact match for this.

I have a fairly large app which is supposed to load pages into divs in another page using the jQuery.load() method. The problem I have is that when loading the same page over and over again into the same div, I see the memory of the browser increase substantially (memory leak). If I call $("*").unbind, I of course do not see a leak, but then everything has been reset, so this isn't reallya fix. The following code example reproduces this problem:

Test1.htm

<head>
   <title></title>
    <script type="text/javascript" language="javascript" src="Scripts/jquery-1.3.2.js"></script>
        <script type="text/javascript" language="javascript">
        <!--
            var i = 0;
        $(document).ready(function() {
            $("#btn").click(
                function() {
                    i++;
                    $("#Test1").load("Test2.htm", null, function() {
                        //$(document).trigger("test");
                    })
                    $("#count").html(i);
                });
        });
    //-->
    </script>
</head>
<body>
    <img id="btn" src="someimage.png" />
    <h3>We are loading Test2.htm into below div</h3>
    <div>
        Count loads =<span id="count">0</span>
    </div>
    <div id="Test1" style="border-style:solid">EMPTY</div>
</body>

Test2.htm = any old html page..

If you load Test1.htm and click the button mutliple times, you'll notice the browser memory steadily increasing. I believe the problem is that the loaded js and DOM elements are never set for garbage collection. In my real world system I have tried removing (elem.remove() or .empty()) the loaded elements, but this doens't really fix the problem. I also have many js files loaded using "src", which I replaced with $.getScript, this seems to have had made a small improvement. These are all workarounds thought, and I wanted to find a real solution for this problem. Any ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Edit: update due to more info provided about test2.htm (the page being loaded)

Original answer (for historical purposes): I don't actually see any leaks in the code/markup you have provided - is it possible the leak is in Test2.htm (which you haven't provided the code/markup for)?

New answer:

I would suggest that it it probably due to either multiple loads of jQuery, or other scripts you have in test2.htm.

Assuming jQuery does not leak by simply instantiating and then nullifying jQuery and $, loading multiple times will keep at least 2 copies of jQuery in memory. When loaded, jQuery keeps a backup of any previous versions of $ and jQuery in _$ and _jQuery - so you are going to have at least 2 copies of jQuery loaded when you use load() multiple times.

The above assumption is most likely not correct however - there is every chance that jQuery has leaks even if you "unload" it by setting $,jQuery,_$ and _jQuery to null - it's not really intended to be loaded multiple times like that (however I'm sure that they allow it intentionally, so you can use noConflict() to load and use two different versions of jQuery if necessary).

You can add a "selector" to a load URL. For example:

$("#Test1").load("Test2.htm body", null, function() { 
  //callback does nothing
});
//or
$("#Test1").load("Test2.htm div#the_Div_I_Want", null, function() { 
  //callback does nothing
});

I would suggest doing this if you are not interested in any scripts in the ajax result, or alternatively if you do want scripts, you'd need to choose a selector to disable only certain elements/scripts, e.g.

/* load with selector "all elements except scripts whose
   src attribute ends in 'jquery.js'" */
$("#Test1").load("Test2.htm :not(script[src$='jquery.js'])", null, function() { 
  //callback does nothing
});

Also of note is that if you leave out the "data" argument (you have it as null), and provide a function as the second argument, jQuery will correctly determine that the second argument is the callback, so

$("#Test1").load("Test2.htm :not(script[src$='jquery.js'])", function() { 
  //callback does nothing
});

is acceptible


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...