美文网首页
关于闭包在ie浏览器会造成内存泄漏的谣言

关于闭包在ie浏览器会造成内存泄漏的谣言

作者: 前端小学生_f675 | 来源:发表于2019-03-27 11:24 被阅读0次

最近翻阅文章又看到了这种说法。。。
23333。。。
从我接触到前端开始起,这种说法就甚嚣尘上。最常见的说法是闭包在IE浏览器可能会造成内存泄漏;一直不知道为什么,直到读到了曾探的《Javascript设计模式与开发实践》这本书,对该问题有详细的描述和探讨。所以刚入行的前端小伙伴,不要再说这句话了。。。

谣言止于智者

局部变量本来应该在函数退出的时候被解除引用,但如果局部变量被封闭在闭包形成的环境中,那么这个局部变量就能一直生存下去。从这个意义上看,闭包的确会使一些数据无法被及时销毁。使用闭包的一部分原因是我们选择主动把一些变量封存在闭包中,因为可能在以后还需要使用这些变量,把这些变量放在闭包中和放在全局作用域,对内存方面的影响是一致的,这里并不能说成是内存泄露。如果在将来需要回收这些变量,我们可以手动把这些变量设为null。

跟闭包和内存泄露有关系的地方是,使用闭包的同时比较容易形成循环引用,如果闭包的作用域链中保存着一些DOM节点,这时候就有可能造成内存泄露。但这本身并非闭包的问题,也并非JavaScript的问题。在IE浏览器中,由于BOM和DOM中的对象是使用C++以COM对象的方式实现的,而COM对象的垃圾收集机制采用的是引用计数策略。在基于引用计数策略的垃圾回收机制中,如果两个对象之间形成了循环引用,那么这两个对象都无法被回收,但循环引用造成的内存泄露在本质上也不是闭包造成的。

Javascript 的垃圾回收机制,我现在知道的有两种:标记、计数。

标记清除:主流策略,并且与此问题无关。

引用计数:容易在循环引用时出现问题的策略。因为计数记录的是被引用的次数,所以循环引用时计数并不会消除。导致无法释放内存。IE 9 - 的问题是在环境中bom和dom不是原生的js对象,而是com对象,而com对象的垃圾收集机制是引用计数策略。换句话说,只要ie中存在着com对象,就会存在循环引用的问题。比如

var element=document.getElementById("someElement");
var myobject=new Object();
myobject.element=element;
element.someObject=myobject;

这个例子中js对象和dom对象之间建立了循环引用,由于存在这个循环引用,即使将com对象从页面移除,也永远不会被回收。为避免类似问题,应该在不使用它们的时候手动把js对象和com对象断开。

myobject.element=null;
element.someObject=null;

ie9之前的浏览器对javascript对象和com对象使用不用的垃圾收集机制,因此闭包在ie的这些版本中会导致一些特殊的问题
比如

function assignHandler(){
var element=document.getElementById("someElement");
element.onclick=function(){
alert(element.Id);
}
}
以上代码创建了一个作为element元素事件处理程序的闭包,这个闭包又创建了一个循环引用,由于匿名函数保存了一个对assignHandler()的活动对象的引用,因此就会导致无法减少element的引用数,因此,只要匿名函数存在,element的引用至少是1,因此所占的内存就无法回收,要改下才能解决

function assignHandler(){
var element=document.getElementById("someElement");
var id=element.Id;

element.onclick=function(){
alert(id);
};
element=null;
}

通过把element.Id的副本保存在本地的一个变量中,并且在闭包中引用改变量消除循环引用,但仅仅做到这一步,还不能消除内存泄漏,因为闭包会引用包含函数的整个活动对象,而其中包含着element;即使不直接引用,包含函数的活动对象中仍然保存着一个引用,因此有必要把element变量设置为null。

同样,如果要解决循环引用带来的内存泄露问题,我们只需要把循环引用中的变量设为null即可。将变量设置为null意味着切断变量与它此前引用的值之间的联系。当垃圾收集器下次运行时,就会删除这些值并回收他们占用的内存。

所以:内存泄漏是由闭包引起的,闭包表示,老夫不背这个锅。。。233333。。。

相关文章:
请详细阅读曾探《Javascript设计模式与开发实践》真心不贵!!!
京东链接

相关文章

  • 关于闭包在ie浏览器会造成内存泄漏的谣言

    最近翻阅文章又看到了这种说法。。。23333。。。从我接触到前端开始起,这种说法就甚嚣尘上。最常见的说法是闭包在I...

  • 十一

    内存泄漏由于IE9之前的版本对JScript对象和COM对象使用不同的垃圾收集例程,因此闭包在IE的这些版本中会导...

  • 杂谈:什么是闭包?闭包会造成内存泄露?

    为什么会流传闭包会导致内存泄露!因为IE浏览器早期的垃圾回收机制,有 bug。 IE浏览器中使用完闭包之后,依然回...

  • 闭包会造成内存泄漏吗?

    前言 在谈内存泄漏这个问题之前先看看JavaScript的垃圾收集机制,JavaScript 具有自动垃圾收集机制...

  • 闭包的作用

    闭包:内部函数保存到外部 当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄漏(内存...

  • 闭包

    闭包:外层函数能够访问内层变量的函数,缺点就是容易造成内存泄漏。

  • 关于AFNetworking内存泄漏的解决方案

    前言 相信不少喜欢对内存进行优化的开发者都注意到了,使用AFNetworking会造成内存泄漏,当然造成内存泄漏的...

  • Android内存泄漏优化

    目录介绍: 01.什么是内存泄漏 02.内存泄漏造成什么影响 03.内存泄漏检测的工具有哪些 04.关于Leakc...

  • 什么是闭包?闭包的好处是什么?

    什么是闭包,闭包的好处 闭包 : 再函数外部可以访问函数内部的变量 好处: 坏处: 容易造成内存泄漏 闭包的相关应...

  • JS中闭包以及垃圾回收机制

    闭包 闭包是指一个函数可以访问另一个函数中的变量。 常见的形式:函数里嵌套函数。 缺点:大量使用闭包会造成内存泄漏...

网友评论

      本文标题:关于闭包在ie浏览器会造成内存泄漏的谣言

      本文链接:https://www.haomeiwen.com/subject/veoavqtx.html