IE8 内存泄露(内存一直增长 )的原因及解决办法

 更新时间:2016年04月06日 09:20:39   作者:hijiankang  
最近开发的时候对页面使用了定时的局部更新,结果在ie6,7和Firefox下,一切正常,而在ie8下过上几个小时就浏览器就崩溃了,显示是内存溢出,下面由脚本之家小编给大家介绍ie8下内存一直增长内存泄漏的原因及解决办法,需要的朋友一起学习吧

最近开发的时候对页面使用了定时的局部更新,结果在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>

相关文章

  • js检测标题与描述中的关键词发现就替换或跳转到别的页面

    js检测标题与描述中的关键词发现就替换或跳转到别的页面

    这篇文章主要介绍了js检测标题与描述中的关键词发现就替换或跳转到别的页面的实现方法,主要是分享它的编程思路与加密方法
    2021-06-06
  • js 异步操作回调函数如何控制执行顺序

    js 异步操作回调函数如何控制执行顺序

    本文为大家讲解下js异步操作时回调函数如何控制执行顺序,感兴趣的朋友可以参考下
    2013-12-12
  • javascript canvas时钟模拟器

    javascript canvas时钟模拟器

    这篇文章主要为大家详细介绍了javascript canvas时钟模拟器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • 非常优秀的JS图片轮播插件Swiper的用法

    非常优秀的JS图片轮播插件Swiper的用法

    最近在一个微信公众号中用到了swiper图片轮播插件。接下来为大家介绍插件的用法,需要的朋友可以参考下
    2017-01-01
  • jsonp跨域获取数据的基础教程

    jsonp跨域获取数据的基础教程

    这篇文章主要给大家介绍了关于jsonp跨域获取数据的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • Layui实现多条件查询的示例代码

    Layui实现多条件查询的示例代码

    本文主要介绍了Layui实现多条件查询,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • js通过googleAIP翻译PHP系统的语言配置的实现代码

    js通过googleAIP翻译PHP系统的语言配置的实现代码

    一同事弄了个系统是php写的,虽然是多语言但没中文!他打算手动翻译2000多个语言配置,真是佩服,知道后想了想,应该有好的法办
    2011-10-10
  • Javascript中的作用域及块级作用域

    Javascript中的作用域及块级作用域

    作用域永远都是任何一门编程语言中的重中之重,因为它控制着变量与参数的可见性与生命周期。下面给大家介绍Javascript中的作用域及块级作用域,需要的朋友参考下吧
    2017-12-12
  • JS中数学计算精度问题的解决方案

    JS中数学计算精度问题的解决方案

    这篇文章主要给大家介绍了JS中数学计算精度问题的解决方案,文中通过代码示例和图文结合给大家讲解非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-12-12
  • ES6学习笔记之map、set与数组、对象的对比

    ES6学习笔记之map、set与数组、对象的对比

    这篇文章主要给大家介绍了关于ES6学习笔记之map、set与数组、对象对比的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-03-03

最新评论