JQuery内存泄漏?

时间:2012-03-01 15:09:24

标签: jquery memory-leaks

在我的应用程序中,我有一个主页面,其中一些面板(DIV)充满了AJAX调用。

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()是用于填充cmp-area面板的函数,其中包含来自服务器的内容。

我注意到每次运行此代码(我使用IE8进行测试)时,内存总是会增长。长时间以这种方式工作会导致整个应用程序性能下降:经过一段时间浏览器无响应!

经过多次测试,似乎问题出在服务器的内容中。

此内容是大多数时间内都包含一些Javascript代码的HTML。

如果此HTML中没有javascript,内存增长不会发生!

如果HTML包含一些javascript(甚至非常短),内存增长仍可能发生。

你可以帮我解决问题所在吗?我的代码中是否存在导致此问题的错误?

感谢您的帮助!

2012年3月2日添加--------

谢谢凯文: 在我的测试中似乎任何javascript都会产生问题:javascript代码越复杂,内存增长越快。

谢谢Kory: 我不知道如何在我的案例中使用你的建议...我正在使用JQuery 1.7.1

1 个答案:

答案 0 :(得分:0)

以下是其他主题的答案:

我认为大卫可能会因涉嫌removeChild漏洞而陷入困境,但我无法在IE8中重现它...它可能会在早期的浏览器中发生,但这不是我们在这里所拥有的。如果我手动removeChild divs没有泄漏;如果我改变jQuery使用outerHTML =''(或者移动到bin然后是bin.innerHTML)而不是removeChild,那么仍然存在泄漏。

在一个消除过程中,我开始在jQuery中删除一些删除。 1.3.2中的第1244行:

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

评论该行没有泄漏。

所以,让我们看一下event.remove,它调用data('events')来查看是否有任何附加到元素的事件。什么是数据?

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

喔。所以它为每个甚至尝试读取数据的元素添加了一个jQuery的uuid-to-data-lookup入口hack属性,其中包括你要删除的元素的每个后代!真傻。我可以通过在它之前放置这条线来短路:

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

似乎在IE8中修复了此案例的泄漏。不能保证它不会破坏jQuery迷宫中的其他东西,但逻辑上它是有道理的。

据我所知,泄漏只是jQuery.cache对象(这是数据存储,而不是真正的缓存)随着为每个删除的新密钥添加而变得越来越大元件。尽管removeData应该删除那些缓存条目,但是当您delete来自对象的密钥时,IE似乎不会恢复空间。

(无论哪种方式,这是我不理解的jQuery行为的一个例子。它在做什么应该是一个简单的简单操作的内幕做得太多了......其中一些是相当可疑的东西使用expando以及jQuery通过正则表达式对innerHTML做什么来防止在IE中显示为属性只是破坏和丑陋。而使得getter和setter具有相同功能的习惯令人困惑,这里导致这个bug。)

[奇怪的是,在内存实际耗尽之前,在jquery.js中偶尔发出完全错误的错误会导致漏洞检测结束......有些事情就像'意外命令',我注意到'nodeName是null或不是第667行的对象,据我所知,甚至不应该运行,更不用说有一个检查nodeName为null! IE在这里没有给我很多信心......]