闭包占用的内存可以被释放吗?

最近一直迷惑这个问题,身边的大佬说标记-清理垃圾回收机制能够回收闭包占用的内存,我了解后隐隐约约觉得不能回收闭包占用的内存,但是也说不出个所以然来,希望还能有大佬说明下。

我有两个问题:

  • 闭包可以手动释放吗?
  • 在GC里,闭包怎么被判定可以被回收?GC处理闭包是否和普通对象一样。
阅读 8.5k
3 个回答

回答一下吧。

其实闭包函数是否可以回收与它的外层函数是无关的,只与是否有引用指向它有关。从这一点上看,闭包函数与普通对象是一样一样儿的。

比如说,调用外层函数,里面返回了一个闭包函数,那么这个闭包函数什么时候回收就不再由外层函数决定了,只由接收者如何处理这个函数有关。

反而是外层函数可能会受到闭包函数的影响,如果外层函数中的变量被闭包函数引用了,那么这个变量必须等到闭包函数回收后才能回收。

这个答案用代码来展开下其他楼各位的回答

const fn = function() {
    let num = 0;
    
    return function() {
        return num += 1;
    }
}

fn()() // 1
fn()() // 1
fn()() // 1

上面这段代码就是最简单的闭包,如果我们此时在浏览器控制台执行这段代码,那么不管执行多少次,控制台得到的结果都是1,实际上 fn 就被回收掉了

但如果我们这么写

const fn = function() {
    let num = 0;
    
    return function() {
        return num += 1;
    }
}

let f1 = fn();

f1(); // 1
f1(); // 2
f1(); // 3

f1 = null;

f1 = fn();

f1(); // 1
f1(); // 2
f1(); // 3

此时的 f1 就是闭包的引用,因此就没法被回收掉
然后使 f1 = null 手动解除引用,再重新赋值后就会发现这个时候闭包也被回收掉了

闭包没地方引用了就可以把gc掉了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏