论坛首页 Web前端技术论坛

IE8中的内存泄露

浏览 12995 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2010-03-17   最后修改:2010-03-17
最近开发的时候对页面使用了定时的局部更新,结果在ie6,7和Firefox下,一切正常,而在ie8下过上几个小时就浏览器就崩溃了,显示是内存溢出,我以为是代码写的不好导致内存泄露,但是ie6,7又正常,调查了一下,原来这是ie8的bug。

问题点

在IE8中,生成特定Dom节点所占用的内存是不会被释放的,即使这些节点被删除内存也不会被释放。

内存泄露的节点类型包括:form、button、input、select、textarea、a、img和objec

其他的大部分节点类型是不会泄露的,例如:span、div、p、table等等。

此问题只发生在IE8,其他浏览器不发生。

如果用户按了F5,IE8会重新刷新页面,首先它会unload window.top,这时候会释放掉内存。如果页面是iframe,则unload此iframe,没有任何反应。看起来只有window.top被 unload,内存才会被释放。

例子

例1

执行下面的代码,IE8就会泄露内存。

function leak1() {
    var node = document.getElementById("TO_AREA");
    node.innerHTML = "<img />";
    node.innerHTML = "";
    node = null;
}


注意:

* 此例子添加了节点,所以会泄露。

* 在中有个div,id为“TO_AREA”。

* 提醒一下,这里没有闭包和循环引用。

例2

下面的代码没有使用innerHTML,但是还是会泄露

function leak2() {
    var node = document.getElementById("FROM_AREA").cloneNode(true);
    node.id = "NEW_AREA";
    document.body.appendChild(node);
    document.body.removeChild(node);
    node = null;
}


注意:

* FROM_AREA 是form的id,而且这里也没有闭包和循环引用。
例3

这是最简单,最直接的例子:

function leak4() {
    var node = document.createElement("IMG");
    document.body.appendChild(node);
    document.body.removeChild(node);
}


注意:

* 如果用span来代替img,就不会有泄露了。

这些例子只在IE8中泄露内存,我在Windows XP, Windows Vista, Windows Server 2008, Windows Server 2008 R2和Windows 7 中的IE8都作了测试,而且使用了IE8中的IE7兼容模式和标准模式,每种情况下都会泄露。
测试页面


关于泄露

内存大小随着时间的推移而增长,但这并不直接导致浏览器崩溃。浏览器使用的内存好像是有上限的,它似乎会从某些内部手段来限制DHTML使用的内存。

内存到达上限后,浏览器会自动处理,例如弹出对话框,显示内存不足。


更多内容,在线内存泄露测试,请参照这里
   发表时间:2010-03-17  
怎么测试的 呢
0 请登录后投票
   发表时间:2010-03-17  
cloudgamer 写道
怎么测试的 呢

你用我例子中的代码,新建一个页面,然后不停的循环,在IE8下,内存会一直增长。或者你访问我的博客,上面有在线测试的页面。

http://www.fogtowerblog.com/web/mem-leak-in-ie8.html
0 请登录后投票
   发表时间:2010-03-17  
fogtower 写道
cloudgamer 写道
怎么测试的 呢

你用我例子中的代码,新建一个页面,然后不停的循环,在IE8下,内存会一直增长。或者你访问我的博客,上面有在线测试的页面。

http://www.fogtowerblog.com/web/mem-leak-in-ie8.html

Iterations: 6800
好像没什么变化呢
0 请登录后投票
   发表时间:2010-03-18  
楼主 你的测试方法根本就不对,所以结论不敢苟同
0 请登录后投票
   发表时间:2010-03-19  
fins 写道
楼主 你的测试方法根本就不对,所以结论不敢苟同

IE8的内存泄露是肯定的,我们公司项目组开发产品的时候已经证实了的,这个没有问题。
请你使用例3的代码,长时间测试,你就会发现问题了,起码一个晚上。
0 请登录后投票
   发表时间:2010-03-19  
泄露内存 你就考虑内存不断增长?

我觉得这个不完全是,应该有别的吧?
0 请登录后投票
   发表时间:2010-03-19  
sodabao 写道
泄露内存 你就考虑内存不断增长?

我觉得这个不完全是,应该有别的吧?


主要是IE6,7,firefox都没有问题,只有IE8在不停的增长,那么应该是内存泄露吧。当然也许是IE8内部机制出了问题,现在主要是没有官方的文档,也就当做是内存泄露了。
0 请登录后投票
   发表时间:2010-03-19   最后修改:2010-03-19
我证明,去年开发时发现和lz同样的现象。结论就是lz所说,IE8的bug。
国外也有人证明,这里有分析和在线测试:
http://com.hemiola.com/?p=5

另外,我想补充的是:

对于IE6/7来说,如果在页面innerHTML中不断局部刷新写入带<form>的内容,<form>所包含的内容也会泄露。测试用例就不摆上来了,lz有兴趣自己试试。

普通的DOM-js互引用造成的泄露用trip,javascript memory detector, sIEve工具可以检测出来,而其他泄露(比如IE8 bug泄露,IE6/7的<form>泄露)是用这些工具检测不出来的。

IE的上述泄露最简单的办法就是全局页面刷新,F5, location.reload(),大部分泄露(包括IE8 bug泄露)就清除了。

还有就是,某些版本的firefox自己就有泄露,或者是add-on产生泄露,基本上不可能完全杜绝。
17 请登录后投票
   发表时间:2010-03-20  
ylssww 写道
我证明,去年开发时发现和lz同样的现象。结论就是lz所说,IE8的bug。
国外也有人证明,这里有分析和在线测试:
http://com.hemiola.com/?p=5

另外,我想补充的是:

对于IE6/7来说,如果在页面innerHTML中不断局部刷新写入带<form>的内容,<form>所包含的内容也会泄露。测试用例就不摆上来了,lz有兴趣自己试试。

普通的DOM-js互引用造成的泄露用trip,javascript memory detector, sIEve工具可以检测出来,而其他泄露(比如IE8 bug泄露,IE6/7的<form>泄露)是用这些工具检测不出来的。

IE的上述泄露最简单的办法就是全局页面刷新,F5, location.reload(),大部分泄露(包括IE8 bug泄露)就清除了。

还有就是,某些版本的firefox自己就有泄露,或者是add-on产生泄露,基本上不可能完全杜绝。


我喜欢这种回复...
关于内存泄露有没有什么专业的工具可以检测呢,上述的几个工具我都没有用过,等等试试,因为不是专业的web开发人员,有时候觉得内存泄露这个很高深,并不知道什么时候回发生内存泄露,也不好花一晚上的时间来测试是否有内存泄露.
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics