我的编程空间,编程开发者的网络收藏夹
学习永远不晚

javascript闭包会造成内存泄漏吗

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

javascript闭包会造成内存泄漏吗

本篇内容介绍了“javascript闭包会造成内存泄漏吗”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1. 标记清除

JavaScript  中最常用的垃圾收集方式是标记清除(mark-and-sweep)。垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记(可以使用任何标记方式)。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。***,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

2. 引用计数

引用计数(reference  counting)的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减1。当这个值的引用次数变成0  时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次再运行时,它就会释放那些引用次数为零的值所占用的内存。

Netscape Navigator 3.0 是最早使用引用计数策略的浏览器,但很快它就遇到了一个严重的问题,请看下面这个例子:

function problem(){     var objectA = new Object();     var objectB = new Object();     objectA.someOtherObject = objectB;     objectB.anotherObject = objectA; }

说明:objectA 和objectB  通过各自的属性相互引用,即这两个对象的引用次数都是2,在采用标记清除策略的实现中,由于函数执行之后,这两个对象都离开了作用域,因此这种相互引用不是个问题。但在采用引用计数策略的实现中,当函数执行完毕后,objectA  和objectB 还说明将继续存在,因为它们的引用次数永远不会是0。假如这个函数被重复多次调用,就会导致大量内存得不到回收。

为此,Netscape 在Navigator 4.0  中放弃了引用计数方式,然而引用计数导致的麻烦并未就此了结。IE9以前中有一部分对象并不是原生JavaScript 对象。例如,其BOM 和DOM  中的对象就是使用C++以COM(Component Object Model,组件对象模型)对象的形式实现的,而COM  对象的垃圾收集机制采用的就是引用计数策略。因此,即使IE 的JavaScript 引擎是使用标记清除策略来实现的,但JavaScript 访问的COM  对象依然是基于引用计数策略的。换句话说,只要在IE 中涉及COM 对象,就会存在循环引用的问题。

比如:

var element = document.getElementById("some_element"); var myObject = new Object(); myObject.element = element; element.someObject = myObject;

DOM 元素(element)与一个原生JavaScript 对象(myObject)之间创建了循环引用。其中,变量myObject  有一个名为element 的属性指向element 对象;而变量element 也有一个属性名叫someObject  回指myObject。由于存在这个循环引用,即使将例子中的DOM 从页面中移除,它也永远不会被回收。

解决办法:将变量设为null从而切断变量与它此前引用的值之间的连接。

myObject.element = null;  element.someObject = null;

看完上面的内容,我来谈正题。

闭包不会引起内存泄漏

由于IE9 之前的版本对JScript 对象和COM 对象使用不同的垃圾收集。因此闭包在IE  的这些版本中会导致一些特殊的问题。具体来说,如果闭包的作用域链中保存着一个HTML 元素,那么就意味着该元素将无法被销毁请看例子:

function assignHandler(){     var element = document.getElementById("someElement");     element.onclick = function(){         alert(element.id);     }; }

以上代码创建了一个作为element  元素事件处理程序的闭包,而这个闭包则又创建了一个循环引用。由于匿名函数保存了一个对assignHandler()的活动对象的引用,因此就会导致无法减少element  的引用数。只要匿名函数存在,element 的引用数至少也是1,因此它所占用的内存就永远不会被回收

解决办法前言已经提到过,把element.id 的一个副本保存在一个变量中,从而消除闭包中该变量的循环引用同时将element变量设为null。

function assignHandler(){     var element = document.getElementById("someElement");     var id = element.id;     element.onclick = function(){         alert(id);     };     element = null; }

“javascript闭包会造成内存泄漏吗”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

javascript闭包会造成内存泄漏吗

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaScript闭包用多会造成内存泄露吗

今天小编给大家分享一下JavaScript闭包用多会造成内存泄露吗的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。.markd
2023-07-05

一文深析闭包用多是否会造成内存泄露

网上有很多关于闭包会造成内存泄露的描述,说闭包会使其中的变量的值始终保持在内存中,一般都不太推荐使用闭包 那么闭包用多了,会造成内存泄露吗?下面一起来看一下吧,希望对大家有帮助。
2023-05-14

vue中的eventBus会产生内存泄漏吗

这篇文章主要介绍了vue中的eventBus会产生内存泄漏吗,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。eventBus是在vue中经常用来解决跨组件消息传递的问题,但对它
2023-06-29

没有resolve及reject的Promise是否会造成内存泄露

这篇文章主要为大家介绍了一直没有resolve及reject的Promise是否会造成内存泄露的问题解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

编程热搜

目录