如果一个闭包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()
无法解决问题,因此会创建一个空的且无法访问的堆栈片段?
答案 0 :(得分:1)
呃。
闭包是一个堆栈框架......
没有。闭包是一个函数,它引用了查找变量所需的外部作用域对象。
当函数开始执行时分配堆栈帧
是。堆栈框架(除了其他东西,如返回地址)将包含具有声明变量的范围对象。或者更确切地说,引用。并非所有变量都在堆栈上分配。
并且在函数返回后没有释放
没有。这就是堆栈的重点 - 当函数返回时,堆栈框架会弹出。
(好像在堆上而不是堆栈上分配了作用域!)
不确定为什么这说“好像”。闭包引用的范围对象在堆上分配。