jQuery load()方法内存泄漏?

时间:2010-01-29 12:53:09

标签: javascript jquery internet-explorer memory-leaks

我一直在寻找这个问题的答案,虽然找到了相关的问题,但我找不到完全相符的问题。

我有一个相当大的应用程序,它应该使用jQuery.load()方法将页面加载到另一个页面的div中。我遇到的问题是,当一遍又一遍地将同一页面加载到同一个div中时,我看到浏览器的内存大幅增加(内存泄漏)。如果我打电话给$(“*”)。取消绑定,我当然看不到泄漏,但是一切都已经重置,所以这不是真正的解决方法。以下代码示例重现此问题:

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 =任何旧的html页面..

如果您加载Test1.htm并单击按钮多次,您会注意到浏览器内存不断增加。我相信问题是加载的js和DOM元素永远不会被设置为垃圾收集。在我的真实世界系统中,我尝试删除(elem.remove()或.empty())已加载的元素,但这并不能解决问题。我也有很多使用“src”加载的js文件,我用$ .getScript替换,这似乎已经有了一些小改进。这些都是想到的解决方法,我想找到解决这个问题的真正解决方案。有什么想法吗?

3 个答案:

答案 0 :(得分:4)

编辑:更新由于提供了有关test2.htm(正在加载的页面)的更多信息

原始答案(出于历史目的):我实际上看不到您提供的代码/标记中的任何泄漏 - 是否可能泄漏在Test2.htm中(您没有提供代码) / markup for)?

新答案:

我建议它可能是由于jQuery的多次加载,或者test2.htm中的其他脚本。

假设jQuery不会通过简单地实例化然后使jQuery$无效而泄漏,多次加载将在内存中保留至少2个jQuery副本。加载后,jQuery会保留$jQuery中任何先前版本的_$_jQuery的备份 - 因此您将至少加载2个jQuery副本你多次使用load()。

上述假设很可能正确 - 但即使您通过设置$jQuery,{“卸载”jQuery,jQuery也有可能泄漏。 {1}}和_$_jQuery - 这并不是真的要多次加载(但是我确信它们是故意允许的,所以你可以使用null来如有必要,加载并使用两个不同版本的jQuery。

您可以在加载网址中添加“选择器”。例如:

noConflict()

如果你对ajax结果中的任何脚本不感兴趣,或者如果你想要脚本,我建议你这样做,你需要选择一个选择器来禁用某些元素/脚本,例如

$("#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
});

另外需要注意的是,如果省略“data”参数(将其作为/* 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 }); ),并提供函数作为第二个参数,jQuery将正确地确定第二个参数是回调,所以

null

是可以接受的

答案 1 :(得分:1)

嗯,也许它只是一些非常基本的东西,但如果我设置$ .ajaxSetup({cache:false});在加载调用之前,我似乎没有遇到问题。现在,当然我的“真实”代码有这个调用,那么为什么我会看到一个问题呢?我相信Tabs UI扩展导致缓存被打开(我实际上并不相信这一点,但在每次加载之前调用false缓存调用似乎都会修复它!)

答案 2 :(得分:0)

好的,所以我终于找到了问题并且它根本不是泄漏(我怀疑),它只是将多个非常复杂的处理程序附加到同一个触发器/事件的结果。我提出了与此有关的问题:

JQuery event model and preventing duplicate handlers