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 Discuz代码中的msn聊天小功能
May 25 Javascript
js 发个判断字符串是否为符合标准的函数
Apr 27 Javascript
修复ie8&amp;chrome下window的resize事件多次执行
Oct 20 Javascript
jQuery Validate表单验证深入学习
Dec 18 Javascript
angularjs中ng-bind-html的用法总结
May 23 Javascript
JS简单实现父子窗口传值功能示例【未使用iframe框架】
Sep 20 Javascript
vue.js打包之后可能会遇到的坑!
Jun 03 Javascript
Vue起步(无cli)的啊教程详解
Apr 11 Javascript
原生JS实现列表内容自动向上滚动效果
May 22 Javascript
js 闭包深入理解与实例分析
Mar 19 Javascript
JS画布动态实现黑客帝国背景效果
Nov 08 Javascript
使用webpack和rollup打包组件库的方法
Feb 25 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修改时间格式的代码
2011/05/29 PHP
php日历制作代码分享
2014/01/20 PHP
php分页代码学习示例分享
2014/02/20 PHP
Yii2使用$this-&gt;context获取当前的Module、Controller(控制器)、Action等
2017/03/29 PHP
Javascript实现的鼠标经过时播放声音
2010/05/18 Javascript
js文件缓存之版本管理详解
2013/07/05 Javascript
js无刷新操作table的行和列
2014/03/27 Javascript
给html超链接设置事件不使用href来完成跳
2014/04/20 Javascript
JS原型链 详解及示例代码
2016/09/06 Javascript
vue.js中过滤器的使用教程
2017/06/08 Javascript
Vue2.0利用vue-resource上传文件到七牛的实例代码
2017/07/28 Javascript
微信小程序自定义toast实现方法详解【附demo源码下载】
2017/11/28 Javascript
JS逻辑运算符短路操作实例分析
2018/07/09 Javascript
angularjs中判断ng-repeat是否迭代完的实例
2018/09/12 Javascript
React 使用Hooks简化受控组件的状态绑定
2019/03/18 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
vue实现多组关键词对应高亮显示功能
2019/07/25 Javascript
JS中的算法与数据结构之队列(Queue)实例详解
2019/08/20 Javascript
[54:17]DOTA2-DPC中国联赛定级赛 RNG vs iG BO3第二场 1月10日
2021/03/11 DOTA
python的else子句使用指南
2016/02/27 Python
使用PyInstaller将Python程序文件转换为可执行程序文件
2016/07/08 Python
详解python3百度指数抓取实例
2016/12/12 Python
Python中.py文件打包成exe可执行文件详解
2017/03/22 Python
python处理csv中的空值方法
2018/06/22 Python
了解不常见但是实用的Python技巧
2019/05/23 Python
在Python中用GDAL实现矢量对栅格的切割实例
2020/03/11 Python
Python闭包及装饰器运行原理解析
2020/06/17 Python
Python列表嵌套常见坑点及解决方案
2020/09/30 Python
Myprotein芬兰官网:欧洲第一运动营养品牌
2019/05/05 全球购物
解释一下ruby中的特殊方法与特殊类
2013/02/26 面试题
幼儿园健康教育方案
2014/06/14 职场文书
股权转让协议范本
2014/12/07 职场文书
本科毕业论文致谢词
2015/05/14 职场文书
python爬虫之爬取笔趣阁小说
2021/04/22 Python
Ajax 的初步实现(使用vscode+node.js+express框架)
2021/06/18 Javascript
如何解决springcloud feign 首次调用100%失败的问题
2021/06/23 Java/Android