IE8 内存泄露(内存一直增长 )的原因及解决办法


Posted in Javascript onApril 06, 2016

最近开发的时候对页面使用了定时的局部更新,结果在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使用的内存。

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

经过自己测试发现 IFrame同样存在这个问题(在IE8下)

补充:iframe内存释放

Ext 核心开发人员Jack的回答是,TabPanelItem在关闭时并不会对自定义到tab中的元素做特殊处理,这部分工作必须在控件外来完成。另一方面, 相关资料称IE在iframe元素的回收方面存在着bug,在通常情况下应该将该元素的src属性值修改为”abort:blank”,并手工将其从 DOM树上移除,然后把脚本中引用它的变量置空并调用CollectGarbage()就可以避免iframe不能正常回收所造成的内存泄露。

<script>
function clearRAM() {
var frame = document.getElementById("ifr_content");
frame.src = 'about:blank';
frame.contentWindow.document.write( '');//清空frame的内容
frame.contentWindow.document.clear();
frame.contentWindow.close(); //避免frame内存泄漏
if (navigator.userAgent.indexOf('MSIE') >= 0) {
if (CollectGarbage) {
CollectGarbage(); //IE 特有 释放内存
//删除原有标记
var tags = document.getElementById("ifrSet");
tags.removeChild(frame);
//添加frameset框架
var _frame = document.createElement('frame');
_frame.src = '';
_frame.name = 'content';
_frame.id = 'ifr_content';
tags.appendChild(_frame);
}
}
}
//主动释放 5秒一次
setInterval( function() {
if (navigator.userAgent.indexOf('MSIE') >= 0) {
if (CollectGarbage) {
//alert(1)
CollectGarbage(); //IE 特有 释放内存
}
}
}, 5000) 
</ script>
Javascript 相关文章推荐
Javascript this指针
Jul 30 Javascript
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
Jun 20 Javascript
JSON 数据格式介绍
Jan 13 Javascript
js固定DIV高度,超出部分自动添加滚动条的简单方法
Jul 10 Javascript
javascript使用输出语句实现网页特效代码
Aug 06 Javascript
jQueryUI DatePicker 添加时分秒
Jun 04 Javascript
工厂模式在JS中的实践
Jan 18 Javascript
详解JS实现简单的时分秒倒计时代码
Apr 25 Javascript
24行JavaScript代码实现Redux的方法实例
Nov 17 Javascript
es6函数中的作用域实例分析
Apr 18 Javascript
Vue如何循环提取对象数组中的值
Nov 18 Vue.js
手写Vue源码之数据劫持示例详解
Jan 04 Vue.js
jQuery实现HTML表格单元格的合并功能
Apr 06 #Javascript
JS中JSON对象和String之间的互转及处理技巧
Apr 06 #Javascript
js老生常谈之this,constructor ,prototype全面解析
Apr 05 #Javascript
实例详解ECMAScript5中新增的Array方法
Apr 05 #Javascript
关于JS中的apply,call,bind的深入解析
Apr 05 #Javascript
javascript中apply、call和bind的使用区别
Apr 05 #Javascript
JavaScript数组去重的两种方法推荐
Apr 05 #Javascript
You might like
php调用方法mssql_fetch_row、mssql_fetch_array、mssql_fetch_assoc和mssql_fetch_objcect读取数据的区别
2012/08/08 PHP
php缓冲输出实例分析
2015/01/05 PHP
PHP树-不需要递归的实现方法
2016/06/21 PHP
PHP使用Nginx实现反向代理
2017/09/20 PHP
详解php用static方法的原因
2018/09/12 PHP
PHP网页缓存技术优点及代码实例
2020/07/29 PHP
js检测客户端不是firefox则提示下载
2007/04/07 Javascript
ExtJs中简单的登录界面制作方法
2010/08/19 Javascript
js实现touch移动触屏滑动事件
2015/04/17 Javascript
JavaScript和JQuery的鼠标mouse事件冒泡处理
2015/06/19 Javascript
Jquery结合HTML5实现文件上传
2015/06/25 Javascript
JavaScript事件详细讲解
2016/06/27 Javascript
JS定时检测任务任务完成后执行下一步的解决办法
2016/12/22 Javascript
angular 用拦截器统一处理http请求和响应的方法
2017/06/08 Javascript
JavaScript用200行代码制作打飞机小游戏实例
2017/06/21 Javascript
JavaScript学习笔记之图片库案例分析
2019/01/08 Javascript
Vue data的数据响应式到底是如何实现的
2020/02/11 Javascript
JS+Canvas实现五子棋游戏
2020/08/26 Javascript
Vue ​v-model相关知识总结
2021/01/28 Vue.js
python验证码识别的实例详解
2016/09/09 Python
Python安装模块的常见问题及解决方法
2018/02/05 Python
matplotlib subplots 调整子图间矩的实例
2018/05/25 Python
Python中文件的写入读取以及附加文字方法
2019/01/23 Python
python抖音表白程序源代码
2019/04/07 Python
TensorFLow 不同大小图片的TFrecords存取实例
2020/01/20 Python
Python MySQL 日期时间格式化作为参数的操作
2020/03/02 Python
初中体育教学反思
2014/01/14 职场文书
《湘夫人》教学反思
2014/02/21 职场文书
2014乡镇党政班子四风问题思想汇报
2014/09/14 职场文书
领导干部作风建设总结
2014/10/23 职场文书
社会实践单位意见
2015/06/05 职场文书
2016教师暑期培训学习心得体会
2016/01/09 职场文书
如何理解Vue简单状态管理之store模式
2021/05/15 Vue.js
Nginx+Windows搭建域名访问环境的操作方法
2022/03/17 Servers
Python学习之os包使用教程详解
2022/03/21 Python
WinServer2012搭建DNS服务器的方法步骤
2022/06/10 Servers