Tho*_*ane 40 ajax jquery memory-leaks
我创建了一个每秒进行一次Ajax调用的网页.在Internet Explorer 7中,它严重泄漏内存(大约15分钟内20 MB).
该计划非常简单.它只运行一个JavaScript函数来进行Ajax调用.服务器返回一个空字符串,JavaScript代码不对其执行任何操作.我用它setTimeout来每秒运行一次这个功能,而我正在使用Drip来观察这个东西.
这是来源:
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('jquery', '1.4.2');
google.load('jqueryui', '1.7.2');
</script>
<script type="text/javascript">
setTimeout('testJunk()',1000);
function testJunk() {
$.ajax({ url: 'http://xxxxxxxxxxxxxx/test', // The url returns an empty string
dataType: 'html',
success: function(data){}
});
setTimeout('testJunk()',1000)
}
</script>
</head>
<body>
Why is memory usage going up?
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
怎么堵这个漏洞?我有一个真正的应用程序,以这种方式更新一个大表,但无人看管它将消耗千兆字节的内存.
编辑:好的,所以经过一些好的建议后,我将代码修改为:
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('jquery', '1.4.2');
google.load('jqueryui', '1.7.2');
</script>
<script type="text/javascript">
setTimeout(testJunk,1000);
function testJunk() {
$.ajax({ url: 'http://xxxxxxxxxxxxxx/test', // The url returns an empty string
dataType: 'html',
success: function(data){setTimeout(testJunk,1000)}
});
}
</script>
</head>
<body>
Why is memory usage going up?
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
但它似乎没有任何区别.我没有对DOM做任何事情,如果我注释掉Ajax调用,内存泄漏就会停止.所以看起来泄漏完全在Ajax调用中.jQuery Ajax本身是否会创建某种循环引用,如果是这样,我该如何释放它?顺便说一句,它不会在Firefox中泄漏.
有人建议在另一个VM中运行测试,看看结果是否相同.我找到了一台运行带有Internet Explorer 8的XP Home的笔记本电脑,而不是设置另一台虚拟机.它出现了同样的问题.
我尝试了一些旧版本的jQuery并获得了更好的结果,但问题并没有完全消失,直到我放弃了jQuery中的Ajax并使用更传统(和丑陋)的Ajax.
Ryl*_*ley 19
这是jQuery上的bug 的链接,以及作为jQuery 1.4.2的建议修复:
--- jquery-1.4.2.js 2010-04-08 12:10:20.000000000 -0700
+++ jquery-1.4.2.js.fixed 2010-04-08 12:10:38.000000000 -0700
@@ -5219,7 +5219,7 @@
// Stop memory leaks
if ( s.async ) {
- xhr = null;
+ xhr.onreadystatechange = null; xhr.abort = null; xhr = null;
}
}
};
Run Code Online (Sandbox Code Playgroud)
注意:这是在jQuery 1.4.4中正式修复的,所以最好的办法是立即升级.
问题似乎在于Internet Explorer中的jQuery 1.4,以及版本1.2和1.3的较小程度.
1.4.0,1.4.1和1.4.2都表现出严重的内存泄漏.
1.2.3,1.2.6,1.3.0,1.3.1和1.3.2都表现出小得多的泄漏(10分钟后约100KB).
我还尝试了一个以更传统的方式调用Ajax的程序版本:
<html>
<head>
<script language="javascript" type="text/javascript">
function getHTTPObject() {
var xmlhttp;
/*@cc_on
@if (@_jscript_version >= 5)
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
@else
xmlhttp = false;
@end @*/
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
if (xmlhttp.overrideMimeType) {
xmlhttp.overrideMimeType("text/xml");
}
} catch (e) {
xmlhttp = false;
}
}
return xmlhttp;
}
var ajaxObject = getHTTPObject();
setTimeout(testJunk,1000);
function testJunk() {
ajaxObject.open('POST', 'http://XXXXXXXXXXXXXXX/delme2', true);
ajaxObject.onreadystatechange = handleAjaxResponse;
ajaxObject.send(null);
}
function handleAjaxResponse() {
if (ajaxObject.readyState==4) {
setTimeout(testJunk,1000);
}
}
</script>
</head>
<body>
<div id="test">Why is memory usage going up?</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这完全摆脱了泄漏.
因此看起来我必须以丑陋的旧方式重复Ajax调用,直到jQuery人员解决这个问题.
我遇到了同样的问题,整个上午都被困住了......直到不久前.问题是在设置onreadystatechange处理程序时创建的循环引用,即IE不够智能,无法中断.因此,解决方案是明确地打破它.但是,显然你不能在处理程序本身内做到这一点(尽管你可以这样做会很方便!).
神奇的声明:
delete request['onreadystatechange'];
Run Code Online (Sandbox Code Playgroud)
您需要记录XMLHttpRequest您设置的每个对象onreadystatechange.然后,在readyState转到4 之后的某个时刻,在对象上做你的魔法.如果您已经在执行重复的AJAX轮询,则检查清理请求的逻辑位置将在同一个轮询循环中.我定义了一个简单的RequestTracker对象来管理我的请求.
这对我有用; 我证实它解决了泄漏问题.这是一个特别引导方式的链接(我会发布更多,但StackOverflow不让我):
eval() 肯定会吃掉内存(当传递字符串到setTimeout进行评估时会发生eval),不要在测试中使用它:
setTimeout('testJunk()',1000);
Run Code Online (Sandbox Code Playgroud)
应该:
setTimeout(testJunk, 1000);
Run Code Online (Sandbox Code Playgroud)
另外一个更好的用途是setInterval()对你想要的重复操作,试试这个:
setInterval(testJunk, 1000);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16671 次 |
| 最近记录: |