在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下测试是没有这些问题的
分享到:
相关推荐
内存泄露,闭包 内存泄露,闭包 内存泄露,闭包
JavaScript闭包技术及IE内存泄漏分析
主要介绍了浅谈js 闭包引起的内存泄露问题的相关资料,需要的朋友可以参考下
} 上面是两个个很显示的循环引用,IE中产生了内存泄露,由于IE的内存回收机制,导至会长期占用内存而不能释放。 但闭包的内存泄露,有些隐蔽。因为闭包的循环引用,是间接的。 代码如下: function iememery(){ var ...
闭包和内存泄漏1
本文通过举例,由浅入深的讲解了解决js函数闭包内存泄露问题的办法,分享给大家供大家参考,具体内容如下 原始代码: function Cars(){ this.name = "Benz"; this.color = ["white","black"]; } Cars.prototype....
IE下的内存泄露问题解决方案、讲解js闭包的所有方式
深度探讨javascript函数的原型链和闭包
JSR-335 将闭包引入了 Java 。闭包在现在的很多流行的语言中都存在,例如 C++、C# 。闭包允许我 们创建函数指针,并把它们作为参数传递。在这篇文章中,将粗略的看一遍Java8的特性,并介绍 Lambda表达式。而且将试...
离散数学-关系,集合,求自反闭包,对称闭包,传递闭包 离散数学-关系,集合,求自反闭包,对称闭包,传递闭包 离散数学-关系,集合,求自反闭包,对称闭包,传递闭包 离散数学-关系,集合,求自反闭包,对称闭包...
实验目的:熟悉warshall算法,掌握求关系的自反闭包,对称闭包和传递闭包的方法。 实验内容:从键盘输入一个关系的关系矩阵,自动求出自反闭包、对称闭包和传递闭包。 计算传递闭包用Warshall算法。 #include...
3) 计算属性集闭包的算法,在课件里有详细说明。方法很简单,但用文字描述很抽象。。。。不解释。。。 4) 计算函数依赖的闭包。此步骤不作要求,但要会方法。个人总结:将所有属性元素组成一个集合(域)记为R;...
C语言实现三种闭包算法,能够实现传递,自反,对称闭包
今天打算换个角度来理解闭包,从内存分配与回收的角度阐述,希望能帮助你真正消化掉所看到的闭包知识,同时也希望本文是你看的最后一篇关于闭包的文章。 大家看本文中的配图时,请牢记箭头的指向。因为它是根
页面之间的关系保持简单,并且在同一站点的不同地址之间进行导航可以快速地清理任何内存泄漏问题。如果存在泄漏,也小到足以忽略。新的Web应用需要实践更高的标准。一个页面可能运行数小时,而不会被导航或者通过Web...
但是,当函数返回了一个闭包时,这个函数的作用域将会一直在内存中保存到闭包不存在为止;使用闭包可以在JavaScript中模仿块级作用域(JavaScript本身没有块级作用域的概念),要点如下: 创建并立即调用一个函数...
闭包文件