IE内存泄漏问题总结

转载 https://blog.csdn.net/rootes/article/details/8784240

1.     什么算IE内存泄漏
l  页面内脚本的动态刷新操作导致IE内存持续上升

l  页面内用F5或右键反复刷新,导致内存不断飙升

l  页面内变量占用的内存在退出该页面后,内存仍然无法回收

l  页面内变量占用的内存在退出该页面所属的iframe后,内存仍然无法回收

 

在此,想说明的是,通常情况下,IE内存泄漏都是极微量的(例如一个span、td或者js变量占用的内存未释放等),对用户使用不会产生影响。但是,在需要实时更新数据或频繁进行进入/退出等反复操作的页面,内存泄漏会给用户带来较差的用户体验,因此,在编写代码时,还是应该注意这个问题。

继续阅读前,请先了解以下几个概念:

l        Scope chain:global和每个function函数都存在一个scope chain,用于保存执行上下文信息,scope即作用域。

l        Closure:函数的闭包

l        Reference type:引用类型,存储在堆中,它通过一个对象指向它(指针引用or地址引用)

2.     IE内存泄漏的官方解释
 Circular References(循环引用)
模式:


说明:

在同一个作用域内(全局域或者函数域内),如果出现js对象引用dom对象,该dom对象又引用同一个作用域内的js对象时,将发生泄漏。

BTW:既然引起IE内存泄露的根本原因是这个,那为啥这个问题在IE7中解决后,IE8中仍然存在类似泄露,不解~~~~

Closures(函数闭包)
模式:


说明:
在一个函数作用域中,存在1个dom对象,该dom对象引用了一个在该函数内的闭包函数(例如执行事件绑定等),且在闭包函数中又引用了上层函数的dom对象,则会导致泄漏。

例:

我的理解是,相当于在ClickEventHandler函数内存于以下隐式调用:
this.elementReference=element; //即存在闭包函数对element的引用
其中 this指ClickEventHandler函数
 

闭包引起泄漏的条件:

外部函数的参数为dom元素

元素属性绑定的func定义在函数内部

 

Cross-Page Leaks
模式:

说明:dom节点的插入顺序不当导致的泄漏。从根节点开始插,最后插顶端节点,才不会泄漏。


Pseudo-Leaks
说明:动态脚本操作导致的问题。例如向html的<script></script>区域动态添加删除脚本代码等。

                             

详细请参考MSDN:http://msdn.microsoft.com/en-us/library/Bb250448

 

BWT:尽管微软列出了以上内存泄漏模型,但是,也有人提出,在IE8下,内存泄漏更为严重,甚至没有循环引用和闭包的情况下,也会出现内存泄漏,并对自己的观点进行了详细分析。请参考:http://com.hemiola.com/2009/11/23/memory-leaks-in-ie8/

 

3.     IE内存泄漏的实践总结
提下,其实IE内存泄漏,归根到底还是IE本身的GC存在缺陷导致的。

虽然官方列举了如上四种模型会导致IE内存泄漏,但是泄漏在代码中的表现形式却多种多样。实际上,很多情况下,IE 消耗的一些垃圾内存都是很难被正常释放,所以在写程序时经常一不小心就造成内存泄漏。以下,就经常使用且容易导致泄漏的代码写法进行总结,在开发中,大家可以将自己的代码与以下模型对照,以尽量避免内存泄漏。

(1) 不要创建孤立节点:创建了某个节点却没有将该节点挂载到dom树上,则节点内存无法回收。

(2) 执行异步AJAX时,状态变迁回调函数使用完后,应当置空。例:

(3) 尽量不要把js数据绑定在dom元素上;如果函数需要创建并返回一个dom元素,最好使用try~finally来释放临时变量。例:

(4) 尽量不要使用以下方式绑定事件。例:


建议使用:

(5)Cross-Page Leaks泄漏。(IE8中该问题已解决)例:


正确的插入方式:

※ 测试发现,这里的onClick仍然会导致泄漏(是否是这样注册的事件无法解除????),目前没有找到好的解决方法。

(6)       不要在创建dom对象时插入脚本。在html的<script></script>内反复动态插入脚本,会导致泄露(Pseudo-Leaks)

(7) 尽量不要使用闭包,特别是在给dom添加响应事件时。

(8) 在删除节点时,对注册事件需要单独回收:IE在移除dom元素时,只会对属性占用的内存进行回收,而所有的注册事件完全没有被回收。例:

(9) 以下节点如果是动态创建,就会导致泄漏(仅IE8下)。

BWT:用文中的实例在XP SP3 的IE8下测试,却没发现泄漏。不知是IE8已解决该BUG还是什么原因~~~???

请参考:http://com.hemiola.com/2009/11/23/memory-leaks-in-ie8/

引文:

The memory used by IE8 to create certain DOM nodes isnever freed, even if those DOM nodes are removed from the document (until window.top is unloaded).There are no closures or circular references involved.

The DOM node types that leak are form, button, input, select, textarea, a, img, andobject. Mostnode types don’t leak, such as span, div, p, table, etc.

Thisproblem only occurs in IE8 (and IE9 and IE10). It does not occur in IE6, IE7,Firefox, or Chrome.

(10)  面向对象方式编程时,需合理释放内存。

4.     总结
IE的内存泄漏,特别是动态的创建元素,绑定事件,移除元素导致的内存泄漏非常普遍,却又很难解决。以上,只是列举了部分典型的例子。更多的,还要从我们开发的应用程序本身出发,总结分析。

 

5.     参考资料
l        http://msdn.microsoft.com/en-us/library/Bb250448

l        http://www.ibm.com/developerworks/cn/web/wa-memleak/index.html

l        http://com.hemiola.com/2009/11/23/memory-leaks-in-ie8/

l        http://www.cnitblog.com/asfman/articles/39727.html

l        http://www.cr173.com/html/6772_1.html

l        http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html


--------------------- 
版权声明:本文为CSDN博主「rootes」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/rootes/article/details/8784240

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值