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 相关文章推荐
jQuery之Deferred对象详解
Sep 04 Javascript
基于jQuery实现的图片切换焦点图整理
Dec 07 Javascript
jQuery中animate动画第二次点击事件没反应
May 07 Javascript
移动端使用localStorage缓存Js和css文的方法(web开发)
Sep 20 Javascript
详解使用fetch发送post请求时的参数处理
Apr 05 Javascript
layer弹窗插件操作方法详解
May 19 Javascript
详解React-Native解决键盘遮挡问题(Keyboard遮挡问题)
Jul 13 Javascript
vue 解决循环引用组件报错的问题
Sep 06 Javascript
vue单页面实现当前页面刷新或跳转时提示保存
Nov 02 Javascript
微信小程序发送短信验证码完整实例
Jan 07 Javascript
《javascript设计模式》学习笔记四:Javascript面向对象程序设计链式调用实例分析
Apr 07 Javascript
JavaScript实现五子棋小游戏
Oct 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漏洞小结
2012/02/05 PHP
PHP数组排序之sort、asort与ksort用法实例
2014/09/08 PHP
php简单实现短网址(短链)还原的方法(测试可用)
2016/05/09 PHP
基于PHP微信红包的算法探讨
2016/07/21 PHP
php实现的二叉树遍历算法示例
2017/06/15 PHP
php之header的不同用法总结(实例讲解)
2017/11/28 PHP
脚本吧 - 幻宇工作室用到js,超强推荐expand.js
2006/12/23 Javascript
javascript multibox 全选
2009/03/22 Javascript
asp.net下利用js实现返回上一页的实现方法小集
2009/11/24 Javascript
Javascript面象对象成员、共享成员变量实验
2010/11/19 Javascript
NodeJS框架Express的模板视图机制分析
2011/07/19 NodeJs
基于datagrid框架的查询
2013/04/08 Javascript
jQuery超精致图片轮播幻灯片特效代码分享
2015/09/10 Javascript
Bootstrap 3.x打印预览背景色与文字显示异常的解决
2016/11/06 Javascript
基于daterangepicker日历插件使用参数注意的问题
2017/08/10 Javascript
JQuery判断正整数整理小结
2017/08/21 jQuery
JS实现的文字间歇循环滚动效果完整示例
2018/02/13 Javascript
Vue与Node.js通过socket.io通信的示例代码
2018/07/25 Javascript
vue基于element-ui的三级CheckBox复选框功能的实现代码
2018/10/15 Javascript
微信小程序-form表单提交代码实例
2019/04/29 Javascript
Vue 中 a标签上href无法跳转的解决方式
2019/11/12 Javascript
原生js实现无缝轮播图
2020/01/11 Javascript
vue使用过滤器格式化日期
2021/01/20 Vue.js
Python3中的真除和Floor除法用法分析
2016/03/16 Python
Python字符编码与函数的基本使用方法
2017/09/30 Python
树莓派与PC端在局域网内运用python实现即时通讯
2019/06/22 Python
PyTorch中 tensor.detach() 和 tensor.data 的区别详解
2020/01/06 Python
python判断元素是否存在的实例方法
2020/09/24 Python
python-图片流传输的思路及示例(url转换二维码)
2020/12/21 Python
CSS3中文字镂空、透明值、阴影效果设置示例小结
2016/03/07 HTML / CSS
Why we need EJB
2016/10/20 面试题
男方父母婚礼答谢词
2014/01/25 职场文书
计算机毕业生求职信
2014/06/10 职场文书
2015年扫黄打非工作总结
2015/05/13 职场文书
生日祝酒词大全
2015/08/10 职场文书
基于go interface{}==nil 的几种坑及原理分析
2021/04/24 Golang