继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

由闭包引出的垃圾回收

青春有我
关注TA
已关注
手记 1244
粉丝 205
获赞 1011

由闭包引出的垃圾回收

闭包的特性

  1. 函数嵌套函数

  2. 函数内部可以引用外部的参数和变量

  3. 参数和变量不会被垃圾回收机制回收

闭包的定义

闭包 是指有权访问另一个函数作用域中的变量的函数,创建闭包最常见的方式就是在一个函数内部创建l另一个函数,通过另一个函数访问这个函数的局部变量

主要应用闭包的场合:设计私有的方法和变量

闭包的优点

  1. 希望一个变量长期驻扎在内存中

  2. 避免全局变量的污染

  3. 私有成员的存在

闭包的缺点

闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题。

在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

在 IE8 以下的版本里,DOM 对象经常会跟 JavaScript 之间产生循环引用。就会造成内存泄漏:

function closure() {    var element = document.getElementById('someElement');
    element. = function(){
        alert(element.id) // 这里导致element一直存在内存中
    }
}

应该将element解除引用来避免内存泄漏

function closure() {    var element = document.getElementById('someElement');    var test = element.id
    element. = function(){
        alert(test) // 这里导致element一致存在内存中
    }
    element = null}

JavaScript 的垃圾回收机制

看完内存泄漏需要了解下JavaScript的垃圾回收机制,首先JavaScript具有自动垃圾回收机制,会找出不再使用的变量,然后释放其占用的内存。常用的方法有两种,即标记清除引用计数

引用计数

语言引擎有一张引用表,保存了内存里面所有的资源(各种值)的引用次数。如果一个值的引用次数为0,就表示这个值不再用到了,因此就可以将这块内存释放。但是引用计数有个最大的问题: 循环引用。

function func() {    let obj1 = {};    let obj2 = {};

    obj1.a = obj2; // obj1 引用 obj2
    obj2.a = obj1; // obj2 引用 obj1}

当函数 func 执行结束后,返回值为 undefined,所以整个函数以及内部的变量都应该被回收,但根据引用计数方法,obj1 和 obj2 的引用次数都不为 0,所以他们不会被回收。

要解决循环引用的问题,最好是在不使用它们的时候手工将它们设为空。上面的例子可以这么做:

obj1 = null;
obj2 = null;

标记清除

JavaScript 中有个全局对象,浏览器中是 window。定期的,垃圾回收期将从这个全局对象开始,找所有从这个全局对象开始引用的对象,再找这些对象引用的对象...对这些活着的对象进行标记,这是标记阶段。清除阶段就是清除那些没有被标记的对象。

总结

闭包只会在IE8以下的版本中才有可能造成内存泄漏问题,在最新版本的浏览器中,可以通过标记清除的方式处理掉内存泄漏,不过闭包的变量会常驻内存,会造成一定的性能问题。



作者:宿雨jj
链接:https://www.jianshu.com/p/65e54525c680


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP