【发布时间】:2017-07-12 22:34:01
【问题描述】:
如果一个闭包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();
事件序列:调用outer()。它的返回地址保存在堆栈中。 foo、bar、f 和 b 都被提升,因此在调用 outer() 时立即分配到堆栈上。 foo() 使用参数5 调用。与任何局部变量一样,函数foo() 的参数也被分配在堆栈上。函数foo() 也通过堆栈返回一个匿名函数。 b 和 bar 会发生同一对事件。我认为foo() 中的匿名函数是闭包,因为它引用了包含它的范围内的变量,但不要介意语义和闭包是什么。我的问题是:我们怎么知道f 和foo() 在b 和bar() 处于活动状态时无法释放,从而创建一个空且无法访问的堆栈片段?
【问题讨论】:
-
引用的句子完全不准确。不要相信。
-
一些 JavaScript 引擎执行的优化可能导致某些变量被存储在堆栈中如果这样做是安全的:stackoverflow.com/q/26150468/5217142
标签: javascript