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 实现的点击复制代码
Mar 24 Javascript
5款Javascript颜色选择器
Oct 25 Javascript
关于JavaScript中原型继承中的一点思考
Jul 25 Javascript
JS调试必备的5个debug技巧
Mar 07 Javascript
7个有用的jQuery代码片段分享
May 19 Javascript
JS &amp; JQuery 动态添加 select option
Jun 08 Javascript
强大的JavaScript响应式图表Chartist.js的使用
Sep 13 Javascript
vue通过路由实现页面刷新的方法
Jan 25 Javascript
Angular使用ControlValueAccessor创建自定义表单控件
Mar 08 Javascript
vue实现日历备忘录功能
Sep 24 Javascript
JavaScript 作用域实例分析
Oct 02 Javascript
vscode中使用npm安装babel的方法
Aug 02 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
fleaphp常用方法分页之Pager使用方法
2011/04/23 PHP
PHP中的数组处理函数实例总结
2016/01/09 PHP
PHP PDOStatement::getColumnMeta讲解
2019/02/01 PHP
php 比较获取两个数组相同和不同元素的例子(交集和差集)
2019/10/18 PHP
PHP中的异常处理机制深入讲解
2020/11/10 PHP
JavaScript Cookie的读取和写入函数
2009/12/08 Javascript
javascript 实用的文字链提示框效果
2010/06/30 Javascript
基于jquery的模态div层弹出效果
2010/08/21 Javascript
Javascript的一种模块模式
2010/09/08 Javascript
js+xml生成级联下拉框代码
2012/07/24 Javascript
jquery实现带复选框的表格行选中删除时高亮显示
2013/08/01 Javascript
html文档中的location对象属性理解及常见的用法
2014/08/13 Javascript
js获取当前日期前七天的方法
2015/02/28 Javascript
jQuery实现订单提交页发送短信功能前端处理方法
2016/07/04 Javascript
基于JSON格式数据的简单jQuery幻灯片插件(jquery-slider)
2016/08/10 Javascript
JS封装的选项卡TAB切换效果示例
2016/09/20 Javascript
JS经典正则表达式笔试题汇总
2016/12/15 Javascript
Angular中$broadcast和$emit的使用方法详解
2017/05/22 Javascript
chorme 浏览器记住密码后input黄色背景处理方法(两种)
2017/11/22 Javascript
讲解vue-router之什么是编程式路由
2018/05/28 Javascript
IE9 elementUI文件上传的问题解决
2018/10/17 Javascript
vue-router重定向和路由别名的使用讲解
2019/01/19 Javascript
Express结合Webpack的全栈自动刷新
2019/05/23 Javascript
js 对象使用的小技巧实例分析
2019/11/08 Javascript
Python函数学习笔记
2008/10/07 Python
Python竟能画这么漂亮的花,帅呆了(代码分享)
2017/11/15 Python
django 捕获异常和日志系统过程详解
2019/07/18 Python
使用python分析统计自己微信朋友的信息
2019/07/19 Python
HTML5 Video标签的属性、方法和事件汇总介绍
2015/04/24 HTML / CSS
娇韵诗加拿大官网:Clarins加拿大
2017/11/20 全球购物
全球性的在线鞋类品牌:Public Desire
2019/04/03 全球购物
物流专业求职信
2014/06/30 职场文书
批评与自我批评总结
2014/10/17 职场文书
2014年环境整治工作总结
2014/12/10 职场文书
Win11 引入 Windows 365 云操作系统,适应疫情期间混合办公模式:启动时直接登录、模
2022/04/06 数码科技
输入框跟随文字内容适配宽实现示例
2022/08/14 Javascript