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 isArray()函数判断对象类型的种种方法
Oct 11 Javascript
自制基于jQuery的智能提示插件一枚
Feb 18 Javascript
asp.net网站开发中用jquery实现滚动浏览器滚动条加载数据(类似于腾讯微博)
Mar 14 Javascript
ajax java 实现自动完成功能
Dec 19 Javascript
JS中的eval 为什么加括号
Apr 13 Javascript
微信小程序 wxapp内容组件 icon详细介绍
Oct 31 Javascript
详解Vue 2.0封装axios笔记
Jun 22 Javascript
Swiper 4.x 使用方法(移动端网站的内容触摸滑动)
May 17 Javascript
jQuery使用bind动态绑定事件无效的处理方法
Dec 11 jQuery
element-ui组件table实现自定义筛选功能的示例代码
Mar 15 Javascript
webpack DllPlugin xxx is not defined解决办法
Dec 13 Javascript
Vue中的this.$options.data()和this.$data用法说明
Jul 26 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
提升PHP执行速度全攻略(上)
2006/10/09 PHP
PHP全概率运算函数(优化版) Webgame开发必备
2011/07/04 PHP
百度工程师讲PHP函数的实现原理及性能分析(三)
2015/05/13 PHP
php代码检查代理ip的有效性
2016/08/19 PHP
php安装扩展mysqli的实现步骤及报错解决办法
2017/09/23 PHP
js 浮动层菜单收藏
2009/01/16 Javascript
jquery实现点击TreeView文本父节点展开/折叠子节点
2013/01/10 Javascript
jQuery中slice()方法用法实例
2015/01/07 Javascript
JavaScript获取文本框内选中文本的方法
2015/02/20 Javascript
jQuery Validation Plugin验证插件手动验证
2016/01/26 Javascript
Javascript发送AJAX请求实例代码
2016/08/21 Javascript
Javascript实现前端简单的路由实例
2016/09/11 Javascript
文件上传插件SWFUpload的使用指南
2016/11/29 Javascript
jquery获取input type=text中的值的各种方式(总结)
2016/12/02 Javascript
Bootstrap CSS布局之列表
2016/12/15 Javascript
bootstrap suggest下拉框使用详解
2017/04/10 Javascript
React diff算法的实现示例
2018/04/20 Javascript
vue2.0 自定义组件的方法(vue组件的封装)
2018/06/05 Javascript
vue实现购物车列表
2020/06/30 Javascript
python中管道用法入门实例
2015/06/04 Python
Python 模拟员工信息数据库操作的实例
2017/10/23 Python
代码分析Python地图坐标转换
2018/02/08 Python
python实现全排列代码(回溯、深度优先搜索)
2020/02/26 Python
Python控制鼠标键盘代码实例
2020/12/08 Python
Python Socket多线程并发原理及实现
2020/12/11 Python
《第一次抱母亲》教学反思
2014/04/16 职场文书
服务承诺口号
2014/05/22 职场文书
陈胜吴广起义口号
2014/06/20 职场文书
学校感恩教育活动总结
2014/07/07 职场文书
期中考试复习计划
2015/01/19 职场文书
个人培训总结
2015/03/05 职场文书
2015年秋季小学开学标语
2015/07/16 职场文书
教师听课学习心得体会
2016/01/15 职场文书
spring cloud 配置中心native配置方式
2021/09/25 Java/Android
V Rising 服务器搭建图文教程
2022/06/16 Servers
Win11如何默认打开软件界面最大化?Win11默认打开软件界面最大化的方法
2022/07/15 数码科技