【发布时间】:2019-06-16 19:17:18
【问题描述】:
想象一下我有这个假设的函数(在 javascript 中):
function paginationRecursive(results) {
let intermediate = retrieveNextPage();
results = results.concat(intermediate)
if (haveAllResults()) return results;
return paginationRecursive(results);
}
intermediate 的每个值是否会一直保存在内存中,直到整个递归处理完成,因此每次递归调用都会增加内存使用量?或者引擎/gc 是否足够聪明,可以在我们调用“更深”的任何时候释放此内存,因为它知道该变量将永远不会被再次使用?
它可能是特定于引擎的(例如V8、SpiderMonkey、Chakra、etc.)所以为了使这个问题不笼统,我更愿意知道 V8 引擎的答案.
【问题讨论】:
-
从你的标题来看,你的真实代码中有一个实际的内存问题吗?顺便说一句,这不是泄漏,因为肯定会在函数结束后清理内存。
-
我没有内存问题,但我正在考虑使用这种方法实现一个功能。我知道当函数结束时内存会被释放,但是在实际函数结束之前处理一个(或多个)调用更深时它会释放内存吗?
-
我认为这并不重要。堆栈帧将被保留,是的,因为 V8 仍然没有正确实现尾调用,但是为
intermediate变量分配的内存可以忽略不计。 -
嗯,你不能假设。我们不知道
intermediate变量中包含的数据的大小。据我们所知,每次可能是 500mb。但是你所说的 V8 没有正确实现尾调用是我感兴趣的。所以如果 GC 需要更多内存,它不会释放所有以前的intermediate值? -
我强烈建议在问题中提及“尾调用”或“尾递归”。这可能会被标记为 stackoverflow.com/questions/37224520/… 的副本
标签: javascript recursion memory-leaks garbage-collection tail-recursion