95 可读性
将光标移到/点击文章中的句子上,可以查看原文。 显示译文      显示原文      双语对照

为什么jquery泄漏内存?

这是我上周发布的问题的后续内容: http://stackoverflow.com/questions/2429056/simple-jquery-ajax-call-leaks-memory-in-ie

我喜欢jquery语法和它的所有优秀特性,但是我有一个页面,通过ajax来自动更新表格单元格中的数据。

所以我为实验创建了两个简单的测试页面。 两个页面每. 1秒执行一次ajax调用。 每次成功的ajax调用后,一个计数器递增,DOM被更新。 脚本在 1000循环后停止。

一个对ajax调用使用 jquery,并更新 DOM 。 另一个使用了 Yahoo API为 ajax,并做了一个 document.getElementById(...). innerHTML来更新 DOM 。

jquery版本的内存泄漏严重。 在滴水( 在XP主页上使用 IE7 ) 中运行,它从 9 MB开始,在大约 48 MB的时候完成,内存在整个时间内呈线性增长。 如果我注释出更新DOM的行,它仍然在 32 MB处完成,这表明即使简单的DOM更新也会泄漏大量内存。 non-jquery版本在大约 9 MB的时间开始并完成,而不管它是否更新了 DOM 。

是否有人很好地解释了导致jquery泄漏如此严重的原因? 我是不是漏掉了一些明显的东西? 是否有循环引用我不知道? 还是jquery有一些严重的内存问题?

这是泄漏( jquery ) 版本的来源:


<html>
 <head>
 <script type="text/javascript" src="http://www.google.com/jsapi"></script>
 <script type="text/javascript">
 google.load('jquery', '1.4.2');
 </script>
 <script type="text/javascript">
 var counter = 0;
 leakTest();
 function leakTest() {
 $.ajax({ url: '/html/delme.x',
 type: 'GET',
 success: incrementCounter
 });
 }
 function incrementCounter(data) {
 if (counter<1000) {
 counter++;
 $('#counter').text(counter);
 setTimeout(leakTest,100);
 }
 else $('#counter').text('finished.');
 }
 </script>
 </head>
 <body>
 <div>Why is memory usage going up?</div>
 <div id="counter"></div>
 </body>
</html>


下面是non-leaky版本:


<html>
 <head>
 <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/yahoo/yahoo-min.js"></script>
 <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/event/event-min.js"></script>
 <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/connection/connection_core-min.js"></script>
 <script type="text/javascript">
 var counter = 0;
 leakTest();
 function leakTest() {
 YAHOO.util.Connect.asyncRequest('GET',
 '/html/delme.x',
 {success:incrementCounter});
 }
 function incrementCounter(o) {
 if (counter<1000) {
 counter++;
 document.getElementById('counter').innerHTML = counter;
 setTimeout(leakTest,100);
 }
 else document.getElementById('counter').innerHTML = 'finished.'
 }
 </script>
 </head>
 <body>
 <div>Memory usage is stable, right?</div>
 <div id="counter"></div>
 </body>
</html>


时间: 原作者: 6个回答

我最初的想法是它与 jquery ajax方法的方式有关:

创建循环引用,尤其对 IE 来说是坏

在内部对象上创建属性,这些属性由于创建的方式和DontDelete属性的设置而无法删除。 有关更多信息,请查看: http://perfectionkills.com/understanding-delete/

不管是哪种方式,垃圾收集器都会被阻止回收垃圾,这将导致内存泄漏失控,尤其是当可疑函数频繁执行时。

原作者:
...