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现实多行信息
Aug 26 Javascript
JQquery的一些使用心得分享
Aug 01 Javascript
简单的js表单验证函数
Oct 28 Javascript
JavaScript动态提示输入框输入字数的方法
Jul 27 Javascript
浅谈JavaScript超时调用和间歇调用
Aug 30 Javascript
JS判断图片是否加载完成方法汇总(最新版)
May 13 Javascript
jQuery实现链接的title快速出现的方法
Feb 20 Javascript
JQuery查找子元素find()和遍历集合each的方法总结
Mar 07 Javascript
详解Vue中一种简易路由传参办法
Sep 15 Javascript
微信小程序实现通过js操作wxml的wxss属性示例
Dec 06 Javascript
Node.js JSON模块用法实例分析
Jan 04 Javascript
JavaScript实现单点登录的示例
Sep 23 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(3) php 函数
2010/02/15 PHP
PHP连接MSSQL时nvarchar字段长度被截断为255的解决方法
2014/12/25 PHP
Yii全局函数用法示例
2017/01/22 PHP
PHP在弹框中获取foreach中遍历的id值并传递给地址栏
2017/06/13 PHP
PHP实现的折半查找算法示例
2017/12/19 PHP
php设计模式之原型模式分析【星际争霸游戏案例】
2020/03/23 PHP
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
jQuery之折叠面板的深入解析
2013/06/19 Javascript
jquery实现多级下拉菜单的实例代码
2013/10/02 Javascript
浅析jQuery EasyUI中的tree使用指南
2014/12/18 Javascript
用JavaScript实现页面重定向功能的教程
2015/06/04 Javascript
jquery实现图片上传前本地预览
2017/04/28 jQuery
NodeJs通过async/await处理异步的方法
2017/10/09 NodeJs
vue2.0 路由模式mode=&quot;history&quot;的作用
2018/10/18 Javascript
Vue CLI3基础学习之pages构建多页应用
2019/06/02 Javascript
flexible.js实现移动端rem适配方案
2020/04/07 Javascript
[02:43]DOTA2英雄基础教程 圣堂刺客
2013/12/09 DOTA
Python装饰器简单用法实例小结
2018/12/03 Python
python读取目录下最新的文件夹方法
2018/12/24 Python
Python时间和字符串转换操作实例分析
2019/03/16 Python
python占位符输入方式实例
2019/05/27 Python
python 初始化一个定长的数组实例
2019/12/02 Python
django自带的权限管理Permission用法说明
2020/05/13 Python
Python  word实现读取及导出代码解析
2020/07/09 Python
洲际酒店集团大中华区:IHG中国
2016/08/17 全球购物
在阿尔卑斯山或希腊度过快乐假期:Alpine Elements
2019/12/28 全球购物
介绍一下内联、左联、右联
2013/12/31 面试题
小学校园之星事迹材料
2014/05/16 职场文书
工地安全质量标语
2014/06/07 职场文书
学生检讨书如何写
2014/10/30 职场文书
2014年图书室工作总结
2014/12/09 职场文书
创业计划书之物流运送
2019/09/17 职场文书
Html5新增了哪些功能
2021/04/16 HTML / CSS
Python控制台输出俄罗斯方块的方法实例
2021/04/17 Python
Python中zipfile压缩包模块的使用
2021/05/14 Python
mysql函数全面总结
2021/11/11 MySQL