读书人

IE8中的内存储器泄露

发布时间: 2012-11-22 00:16:41 作者: rapoo

IE8中的内存泄露
最近开发的时候对页面使用了定时的局部更新,结果在ie6,7和Firefox下,一切正常,而在ie8下过上几个小时就浏览器就崩溃了,显示是内存溢出,我以为是代码写的不好导致内存泄露,但是ie6,7又正常,调查了一下,原来这是ie8的bug。

问题点

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

内存泄露的节点类型包括: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使用的内存。

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


更多内容,在线内存泄露测试,请参照这里。 1 楼 cloudgamer 2010-03-17 怎么测试的 呢 2 楼 fogtower 2010-03-17 cloudgamer 写道怎么测试的 呢
你用我例子中的代码,新建一个页面,然后不停的循环,在IE8下,内存会一直增长。或者你访问我的博客,上面有在线测试的页面。

http://www.fogtowerblog.com/web/mem-leak-in-ie8.html 3 楼 cloudgamer 2010-03-17 fogtower 写道cloudgamer 写道怎么测试的 呢
你用我例子中的代码,新建一个页面,然后不停的循环,在IE8下,内存会一直增长。或者你访问我的博客,上面有在线测试的页面。

http://www.fogtowerblog.com/web/mem-leak-in-ie8.html
Iterations: 6800
好像没什么变化呢 4 楼 fins 2010-03-18 楼主 你的测试方法根本就不对,所以结论不敢苟同 5 楼 fogtower 2010-03-19 fins 写道楼主 你的测试方法根本就不对,所以结论不敢苟同
IE8的内存泄露是肯定的,我们公司项目组开发产品的时候已经证实了的,这个没有问题。
请你使用例3的代码,长时间测试,你就会发现问题了,起码一个晚上。
6 楼 sodabao 2010-03-19 泄露内存 你就考虑内存不断增长?

我觉得这个不完全是,应该有别的吧? 7 楼 fogtower 2010-03-19 sodabao 写道泄露内存 你就考虑内存不断增长?

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

主要是IE6,7,firefox都没有问题,只有IE8在不停的增长,那么应该是内存泄露吧。当然也许是IE8内部机制出了问题,现在主要是没有官方的文档,也就当做是内存泄露了。
8 楼 ylssww 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产生泄露,基本上不可能完全杜绝。 9 楼 Cresting 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开发人员,有时候觉得内存泄露这个很高深,并不知道什么时候回发生内存泄露,也不好花一晚上的时间来测试是否有内存泄露. 10 楼 dreampuf01 2010-03-21 因为这些元素都很常用,解决的方案也只有创建一个document...用完后再reload? 11 楼 zhajie 2010-03-22

jquery 在ie8下内存泄漏严重,其他的ie版本没测试过。

firefox,和chrome都没有这个问题。 12 楼 fins 2010-03-22 我越看越糊涂 大家到底是怎么定义内存泄露的啊??

我觉得: 刷新页面, 最小化浏览器窗口然后再还原,之后依然不能释放的多余的内存 才算真正意义上的内存泄露. 13 楼 xiao-qiang163 2010-03-22 写得很好! 长见识了,谢谢

读书人网 >Web前端

热点推荐