2012-03-01 49 views
0

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

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-区域面板从服务器获得的功能。

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

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

此内容是一个HTML代码,大部分时间内都带有一些Javascript代码。

如果这个HTML里面没有javascript,内存的增长就不会发生!

如果HTML包含一些JavaScript(甚至很短),内存的增长仍然可能发生。

你能帮我解决问题出在哪里吗?我的代码中是否有错误产生这个问题?

感谢您的帮助!

新增2012年3月2日--------

感谢凯文: 在我的测试看来任何JavaScript产生的问题:更复杂的JavaScript代码和存储的增长更为迅速。

感谢Kory: 我不知道如何使用您的建议在我的情况...我使用JQuery 1.7.1

+0

ajax加载页面上的JavaScript是什么? – 2012-03-01 15:26:54

+0

已经在这里解答:http://stackoverflow.com/questions/1462649/jquery-memory-leak-with-dom-removal – 2012-03-01 15:50:51

回答

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-up条目hack属性,其中包括您要删除的元素的每个后代!多么愚蠢。我可以短路,通过加入这一行刚收到:

// Don't create ID/lookup if we're only reading non-present data 
if (!id && data===undefined) 
    return undefined; 
这似乎修复泄漏的这种情况下,IE8

。不能保证它不会在jQuery迷宫中破坏别的东西,但从逻辑上讲它是有道理的。

据我所知,泄漏只是对象(这是数据存储,而不是一个真正的缓存本身)变得越来越大,因为为每个被删除的元素添加了新的密钥。尽管removeData应该删除这些缓存条目,但是,当您从对象获取密钥时,IE似乎不会恢复空间。 (不管怎样,这是一个我不明白的jQuery行为类型的例子,它对于什么应该是一个简单的简单操作来说太过分了......其中有些是相当有问题的用expando和jQuery对innerHTML通过正则表达式做的事情,以防止在IE中显示为属性,这一切都是破碎和丑陋的,而且让getter和setter具有相同功能的习惯令人困惑,在这里,结果)

[奇怪的是,长时间的泄漏测试最终偶尔会在内存实际用完之前给jquery.js中的完全虚假错误...有些事情像'意外的命令',并且我在第667行注意到'nodeName为空或不是对象' ,据我所知,甚至不应该运行,更不用说在那里有一个检查nodeName为空! IE在这里没有给我太多信心...]