在ie的内存泄露中跨页面的泄露是最严重的,浏览器刷新了仍然无法释放掉泄露占用的资源,造成访问速度越来越慢,内存占用越来越大
closure引起cross page leak的主要原因是closure和dom元素的互相引用
看这个例子:
<div id="bb"><div id="aa">cc</div></div>
<script type="text/javascript">
function leakTest(){
var a=[];//用来加大闭包资源占用,方便观察
for(var i=0;i<100000;i++){
a.push('a');
}
var divA=document.getElementById('aa');
divA.kk=function(){};
divA.parentNode.removeChild(divA);
}
leakTest();
</script>
用sIEve看下发现这个页面每次刷新都会产生跨页面泄露,ie内存占用大了7MB,具体fins的文章中有过介绍
在这个例子中我们在leakTest()中创建了一个内部匿名函数并在dom元素aa的自定义属性kk中保存了他的引用,这就产生了一个闭包
divA.parentNode.removeChild(divA);
这句是产生泄露的主要原因,移除了aa并不会使这个节点消失,只不过在dom树上无法访问这个节点而已,由于闭包的存在divA这个局部变量不会被释放,而divA中保存着aa的引用,这就形成了一个循环引用,闭包保存了dom元素aa的引用,dom元素aa的自定义属性kk又保存了闭包内部的匿名函数的引用,所以在页面刷新的时候IE无法释放掉这个aa和闭包的资源,在我这个例子中就比较吓人,刷一下涨几MB内存
让我们删掉divA.parentNode.removeChild(divA);这句试试,发现没有泄露发生
我推测IE在刷新时会强行释放掉dom树上的元素,而不存在于dom树中的节点不会强行释放,所以造成了跨页面泄露,这是我的个人推测,有别的意见欢迎讨论
怎么解决这个问题呢,其实我们只要打断引用链就行了
<div id="bb"><div id="aa">cc</div></div>
<script type="text/javascript">
function leakTest(){
var a=[];
for(var i=0;i<100000;i++){
a.push('a');
}
var divA=document.getElementById('aa');
divA.kk=function(){};
divA.parentNode.removeChild(divA);
divA=null;
}
leakTest();
</script>
或者
<div id="bb"><div id="aa">cc</div></div>
<script type="text/javascript">
function leakTest(){
var a=[];
for(var i=0;i<100000;i++){
a.push('a');
}
document.getElementById('aa').kk=function(){};
document.getElementById('aa').parentNode.removeChild(document.getElementById('aa'));
//这个例子不保存aa的应用,也不会引起泄露
}
leakTest();
</script>
or
<div id="bb"><div id="aa">cc</div></div>
<script type="text/javascript">
function leakTest(){
var a=[];
for(var i=0;i<100000;i++){
a.push('a');
}
var divA=document.getElementById('aa');
divA.kk=function(){};
divA.parentNode.removeChild(divA);
return divA;
}
var divA=leakTest();
divA.kk=null; //这个可以看到内存占用比上面少了7MB,因为解除了对闭包内部函数的引用,闭包占用的资源被释放了
</script>
通过上面的例子可以看出,如果某个函数中dom元素保存了内部函数的引用,就会形成闭包,很容易引起泄露,务必小心
另firefox下测试是没有这些问题的
分享到:
相关推荐
本文将深入探讨IE下的内存泄露问题及其解决方案,并解析JavaScript闭包的多种用法,帮助开发者更好地理解和应对这一挑战。 ### IE内存泄露问题 #### 问题概述 在IE中,内存泄露主要是由于DOM元素与JavaScript对象...
“JS关于ie的内存泄漏与javascript内存释放资料.doc”和“Js内存泄漏及解决方案.doc”可能详细解释了JavaScript中如何发生内存泄漏,尤其是在IE浏览器中的特殊情况。IE浏览器因为其独特的内存管理机制,如活动对象链...
JavaScript内存泄露是一个重要的性能优化话题,尤其是在...对于IE浏览器,由于其早期版本的垃圾收集机制不完善,内存泄露问题更为突出,文档《理解并解决IE的内存泄漏方式》可能会提供更具体的针对IE浏览器的解决方案。
JavaScript内存泄漏是一个重要的主题,尤其是在现代Web开发中,因为页面长时间保持...在编写JavaScript代码时,应养成良好的编程习惯,如及时解除引用,谨慎使用闭包,以及正确处理跨页面引用,以减少内存泄漏的风险。
这种情况下,如果闭包和外部对象形成循环引用,内存泄露就可能发生。 例如: ```javascript function outer() { var obj = {}; function inner() { // 这里引用了 obj 对象 } obj.inner = inner; } ``` 在这...
本文将详细探讨JavaScript内存泄漏的原因,并展示一些常见的内存泄漏模式,以及如何解决这些问题。 首先,JavaScript 是一种垃圾收集语言,意味着对象创建时会分配内存,在没有更多引用时由浏览器回收这些内存。...
本文将深入探讨IE8内存泄露的原因以及相应的解决策略。 首先,内存泄露的根本原因在于IE8的一个已知bug。在IE8中,当创建某些特定类型的DOM(文档对象模型)节点,如form、button、input、select、textarea、a、img...
3. **闭包引起的内存泄露**: 当函数内部引用了外部作用域的变量,尤其是引用了DOM对象时,会形成闭包,导致内存无法释放。比如给DOM元素添加事件监听器,内部函数引用了该元素,即使元素从DOM中移除,闭包依然存在...
这篇文章将深入探讨在IE8中AngularJS内存泄漏的成因、测试方法以及如何解决。 **1. AngularJS与IE8的兼容性** AngularJS 1.x版本在设计时并未充分考虑对IE8的全面支持,因为IE8并不完全支持ES5,而AngularJS依赖于...
首先,闭包会导致函数中的变量长期保存在内存中,这可能会消耗大量内存资源,特别是在IE浏览器中,不恰当的使用可能会导致内存泄露。为了避免这种情况,我们应当在不需要的变量时,显式地将它们从内存中清除。 其次...
然而,闭包也存在一定的缺点,由于它会保留对外部变量的引用,可能导致内存泄漏,特别是在长时间运行或大量使用闭包的应用中,需要注意内存管理。 闭包有三个关键特性: 1. 内部函数可以访问外部函数的变量。 2. ...
本文将深入探讨如何实现最佳的`addEvent`事件绑定方法,以及如何解决与之相关的内存泄漏和兼容性问题。 首先,让我们回顾一下传统事件绑定的方式,例如在给定的代码示例中,通过循环将`openClose`函数直接赋值给`H3...
- **闭包**:闭包的原理及应用场景,避免内存泄漏的方法。 - **作用域**:变量的作用域链,函数的作用域规则。 - **事件机制**:DOM事件流、事件委托、事件捕获与冒泡等。 - **异步编程**:回调函数、Promise、async...
第一,`img.onload`使用匿名函数,形成闭包,可能导致IE6等旧版浏览器的内存泄漏。因为闭包会保持对外部变量的引用,导致`img`对象无法被垃圾回收。为了解决这个问题,可以在`onload`事件触发后将`img.onload`设为`...
定时器是实现动态效果和异步操作的重要工具,但需要注意的是,它们与浏览器的渲染循环相关联,可能导致阻塞或内存泄漏,因此在使用时需谨慎。 2. 图像对象: 在JavaScript中,我们可以使用`<img>`元素的`src`属性...
### 面试JS考察点详解 #### 1. 原型链 **定义**:JavaScript中的每个函数都有一个`...以上只是JavaScript面试中可能涉及的一些关键知识点,后续还将继续深入探讨其他方面,例如内存泄漏问题、长连接的应用等。
- **Chrome DevTools**的使用:性能分析、内存泄漏检测、网络请求追踪等。 - **代码审计**:使用Webpack、Babel等工具进行代码压缩、优化。 8. **跨平台兼容性** - **浏览器差异**:了解不同浏览器的特性与兼容...
在本文中,我们将深入探讨如何动态地添加和移除事件监听器,以及这对网页性能和用户体验的影响。 首先,让我们了解事件处理的基本方式。在HTML中,我们可以通过属性来静态绑定事件,如`onclick`、`onmouseover`等。...