javascript,循环引用和内存泄漏
从我记得的不太遥远的过去,Javascript解释器在遇到循环引用时遭受了内存泄漏问题。javascript,循环引用和内存泄漏
在最新的浏览器中它仍然是这种情况吗? (如铬,FF 3.5等)
绝大多数泄漏我们当您在JavaScript对象和DOM节点等主机对象之间进行参考循环时,特别在IE6-7中讨论JavaScript。
在IE6中这是特别有害的,因为当你离开页面时你没有得到回忆;它已经消失,直到你退出浏览器。在IE7中清除页面现在可以返回内存,但是当你有一个长时间运行的应用程序时,你仍然会遇到困难。 IE8通过将DOM节点转换为本地JavaScript对象而不是主机对象来正确地解决了这个问题。 (你仍然可以在IE8中通过在参考循环中包含其他非本机对象,如ActiveX对象来触发泄漏)。
在所有浏览器中随机出现的潜在的小内存泄漏仍然存在,特别是旧版本。但是没有一种方法可以轻松分类并避免出现类似于IE refloop问题的情况。
关于Internet Explorer 8中 - 他们说,他们在MS IE8有固定的:http://msdn.microsoft.com/en-us/library/dd361842(VS.85).aspx
类似的线程在这里*上:Do you know what may cause memory leaks in JavaScript?
添加到bobince答案,我做了一些测试IE8。
我试图在http://www.javascriptkit.com/javatutors/closuresleak/index.shtml
他们正在泄漏内存中没有一个提供几乎所有的例子了(至少在可感知的方式),除例子去除仍附有他们事件的子节点。
这种类型的例子我认为最好在他的queuetest2中用Douglas Crockford来解释。
这一个在IE8仍然出现内存泄漏,它是很容易测试,只需运行the test script,看着Windows任务管理器 - 性能 - PF使用率。你会看到PF Usage每循环增加近1MB(非常快)。
在IE8但内存被释放在页面卸载(如导航到一个新的页面或重新加载在同一页),显然也当完全关闭浏览器。因此,为了使最终用户能够感知IE8上的内存泄露(因为降低了系统性能),他需要长时间保持在同一页面上,这在目前的日子里可能会频繁发生在AJAX上,但是这个页面还需要做数百个子节点去除元素并附带事件。
道格拉斯Crockford的测试强调添加了10000节点浏览器,然后取出,这是极好的展示你的问题,但在现实生活中我从未有过一个网页,删除超过10个元素。INMHO通常使用display: none
而不是删除整个节点集合,这就是为什么我不使用removeChild
那么多。
对于谁可能更感兴趣的是IE8内存泄漏上面解释的,我做了另一个测试,它似乎MEM泄漏不到位的appendChild/removeChild
添加使用innerHTML
时都在IE8显示/删除附加事件的子元素。因此很明显,道格拉斯Crockford的purge function(由他提出,以防止内存泄漏在IE)是没有必要再在使用IE8时innerHTML
至少...
(EDITED得益于以下 4esn0k评论) ...而且道格拉斯Crockford purge function在IE8上完全不起作用,他的代码var a = d.attributes
返回在IE8上运行时添加的属性(或任何其他onevent
属性)(它们在IE7上返回)。
道格拉斯Crockford的说:
“清除功能应该删除任何元件之前被调用,要么 由removeChild之方法,或通过 设置的innerHTML属性”。
我这里提供测试代码:
<body>
<p>queuetest2 similar to the one provided by Douglas Crockford
at http://www.crockford.com/javascript/memory/leak.html
<br>but this one adds/removes spans using innerHTML
instead of appendChild/removeChild.</p>
<div id="test"></div>
<script>
/* ORIGINAL queuetest2 CODE FROM DOUGLAS CROCKFORD IS HERE
http://www.crockford.com/javascript/memory/queuetest2.html */
(function (limit, delay)
{
var n = 0;
var add = true;
function makeSpan(n)
{
var div = document.getElementById('test');
//adding also an inline event to stress more the browser
div.innerHTML = "<span onmouseover=\"this.style.color = '#00ff00';\">" + n + "</span>";
var s = div.getElementsByTagName('span')[0];
s.onclick = function(e)
{
s.style.backgroundColor = 'red';
alert(n);
};
return s;
}
function process(n)
{
if(add)
s = makeSpan(n);
else
s.parentNode.innerHTML = ""; //removing span by clearing the div innerHTML
add = !add;
}
function loop()
{
if (n < limit)
{
process(n);
n += 1;
setTimeout(loop, delay);
}
}
loop();
})(10000, 10);
</script>
</body>
“道格拉斯克罗克福德净化功能”对IE 8来说有帮助吗?似乎,由于IE8(在IE8模式下,不兼容模式)“s.onclick”未映射到“onclick”属性,因此清除无法在属性中找到“onclick”。我对吗? – 4esn0k 2012-01-26 06:40:05
@ 4esn0k:对不起,但我不确定你的意思。 – 2012-01-31 17:16:08
var s = document.createElement('div'); s.onclick = function(){}; var a = s.attributes; for(var i = 0; i
+1:长期寻找这个perl的智慧。 – 2010-09-08 12:24:12
@Marco Demaio嗯,这个http://ecmascript.stchur.com/blogcode/ie_innerhtml_memleak/leak.html仍然在IE9中以标准或怪癖模式泄漏(win7 64bit),请务必在监视专用字节时使用进程资源管理器..叹了口气.. – 2012-08-02 01:41:38
@AlexanderN:实际上IE8 WXP你建议的页面不会泄漏。我使用简单的“Windows任务管理器”(“性能”选项卡)来查看页面是否泄漏,在这种情况下,您会看到“PF Usage”增加得越来越多。 – 2012-08-17 15:49:09