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 操作文件 实现方法小结
Jul 02 Javascript
解析jquery中的ajax缓存问题
Dec 19 Javascript
node.js中的fs.existsSync方法使用说明
Dec 17 Javascript
基于JavaScript实现单选框下拉菜单添加文件效果
Jun 26 Javascript
vue货币过滤器的实现方法
Apr 01 Javascript
微信小程序开发入门基础教程
Apr 19 Javascript
js防刷新的倒计时代码 js倒计时代码
Sep 06 Javascript
详解动画插件wow.js的使用方法
Sep 13 Javascript
AngularJS中的作用域实例分析
May 16 Javascript
详解js常用分割取字符串的方法
May 15 Javascript
vue input标签通用指令校验的实现
Nov 05 Javascript
JS实现简易图片自动轮播
Oct 16 Javascript
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
Oracle 常见问题解答
2006/10/09 PHP
编写php应用程序实现摘要式身份验证的方法详解
2013/06/08 PHP
学习thinkphp5.0验证类使用方法
2017/11/16 PHP
PHP+MySQL实现模糊查询员工信息功能示例
2018/06/01 PHP
JavaScript类和继承 constructor属性
2010/03/04 Javascript
Javascript实现滚动图片新闻的实例代码
2013/11/27 Javascript
div浮层,滚动条移动,位置保持不变的4种方法汇总
2013/12/11 Javascript
javascript删除字符串最后一个字符
2014/01/14 Javascript
浅谈JavaScript中定义变量时有无var声明的区别
2014/08/18 Javascript
javascript关于继承的用法汇总
2014/12/20 Javascript
nodejs实现获取某宝商品分类
2015/05/28 NodeJs
jQuery动态改变多行文本框高度的方法
2016/09/07 Javascript
AngularJS实现树形结构(ztree)菜单示例代码
2016/09/18 Javascript
不使用 JS 匿名函数理由
2017/11/17 Javascript
使用vux实现上拉刷新功能遇到的坑
2018/02/08 Javascript
微信 jssdk 签名错误invalid signature的解决方法
2019/01/14 Javascript
tensorflow训练中出现nan问题的解决
2018/02/10 Python
Python爬虫包BeautifulSoup学习实例(五)
2018/06/17 Python
Python不使用int()函数把字符串转换为数字的方法
2018/07/09 Python
python爬取哈尔滨天气信息
2018/07/14 Python
django 外键model的互相读取方法
2018/12/15 Python
python中实现控制小数点位数的方法
2019/01/24 Python
详解Python Matplot中文显示完美解决方案
2019/03/07 Python
OpenCV 表盘指针自动读数的示例代码
2020/04/10 Python
python爬虫实例之获取动漫截图
2020/05/31 Python
澳大利亚在线时尚精品店:Hello Molly
2018/02/26 全球购物
eBay加拿大站:eBay.ca
2019/06/20 全球购物
Java面试中常遇到的问题,也是需要注意的几点
2013/08/30 面试题
会计岗位职责模板
2014/03/12 职场文书
2014个人四风对照检查材料思想汇报
2014/09/18 职场文书
县委常委班子专题民主生活会查摆问题及整改措施
2014/09/27 职场文书
2014大学校园光棍节活动策划书
2014/09/29 职场文书
学术研讨会欢迎词
2015/01/26 职场文书
HTML中的表单Form实现居中效果
2021/05/25 HTML / CSS
Nginx stream 配置代理(Nginx TCP/UDP 负载均衡)
2021/11/17 Servers
MySQL多表查询机制
2022/03/17 MySQL