闭包(在Javascript中)会导致堆栈碎片吗?

时间:2017-07-12 22:34:01

标签: javascript

如果一个闭包is是一个

的堆栈框架
  

在函数开始执行时分配,之后不释放   函数返回(好像在堆上分配了一个'堆栈帧')   而不是堆栈!),

这不意味着堆栈可能会碎片化吗?

例如,调用foo(),然后调用bar()。两者都是封闭的。是否有任何场景会使foo()的闭包超出范围,或以其他方式成为解除分配的候选者(在堆栈的情况下解除分配仅仅意味着运行时将堆栈指针移回,释放空间)而bar()继续需要堆栈空间?

如果这样的事件反复发生,那么堆栈上会发生堆碎片的等价物,除了堆栈工作的本质,空间会丢失。显然这并没有发生。是什么阻止它发生?

我特别感兴趣的是JavaScript的上下文,其中一个人甚至不知道运行代码的机器,但这个问题适用于任何函数式语言。

努力使问题脚踏实地......

请考虑以下代码示例。

outer = function() {
    var foo = function(v) {
        return function() { return v; }
    }

    var bar = function(w) {
        return function() { return w; }
    }

    var f = foo(5);
    var b = bar(7);
    document.writeln(f());
    document.writeln(b());
    document.writeln(f());
    document.writeln(b());
}
outer();

stack and heap

事件序列:调用outer()。它的返回地址保存在堆栈中。 foobarfb都已悬挂,因此只要调用outer()就会在堆栈中分配。使用参数foo()调用5。与任何局部变量一样,函数foo()的参数也会在堆栈上分配。函数foo()也通过堆栈返回匿名函数。 bbar会发生同一对事件。我认为foo()中的匿名函数是闭包,因为它引用了包含它的作用域中的变量,但从不介意语义和什么是闭包。我的问题是:当ffoo()还活着时,我们怎么知道bbar()无法解决问题,因此会创建一个空的且无法访问的堆栈片段?

1 个答案:

答案 0 :(得分:1)

呃。

  

闭包是一个堆栈框架......

没有。闭包是一个函数,它引用了查找变量所需的外部作用域对象。

  

当函数开始执行时分配堆栈帧

是。堆栈框架(除了其他东西,如返回地址)将包含具有声明变量的范围对象。或者更确切地说,引用。并非所有变量都在堆栈上分配。

  

并且在函数返回后没有释放

没有。这就是堆栈的重点 - 当函数返回时,堆栈框架会弹出。

  

(好像在堆上而不是堆栈上分配了作用域!)

不确定为什么这说“好像”。闭包引用的范围对象在堆上分配。