Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用尾部递归时内存泄漏_Javascript_Recursion_Memory Leaks_Garbage Collection_Tail Recursion - Fatal编程技术网

Javascript 使用尾部递归时内存泄漏

Javascript 使用尾部递归时内存泄漏,javascript,recursion,memory-leaks,garbage-collection,tail-recursion,Javascript,Recursion,Memory Leaks,Garbage Collection,Tail Recursion,假设我在javascript中有一个假设函数: function paginationRecursive(results) { let intermediate = retrieveNextPage(); results = results.concat(intermediate) if (haveAllResults()) return results; return paginationRecursive(results); } 在整个递归处理完成之前,中间值的每个值是否都

假设我在javascript中有一个假设函数:

function paginationRecursive(results) {
  let intermediate = retrieveNextPage();
  results = results.concat(intermediate)
  if (haveAllResults()) return results;
  return paginationRecursive(results);
}
在整个递归处理完成之前,中间值的每个值是否都会保留在内存中,从而每次增加每次递归调用的内存使用量?或者引擎/gc是否足够聪明,可以在任何时候释放内存,因为它知道变量永远不会被再次使用


可能是因为它是特定于发动机的,例如,为了使这个问题不太宽泛,我更愿意知道V8发动机的答案。

我认为现在的答案是应该释放中间变量,但不会

ES6确实谈到甚至需要优化:

尾部位置调用必须释放任何瞬态内部 与当前正在执行的函数执行关联的资源 在调用目标函数或重用这些资源之前 支持目标函数

下面是JS中TCO尾部调用优化的概述

总而言之,该页面链接到此表,显示几乎没有运行时真正支持它:

提供一些见解和链接,其中包括:

[…]V8团队强烈支持通过特殊的 语法。有一个名为语法尾部调用的待定TC39建议 为了明确这一行为,委员会成员从 Mozilla和微软。[…]V8团队计划解决 装运前的下一次TC39会议上的问题是正确的 默认情况下,尾部调用或语法尾部调用

也就是说,V8不希望按照规范实现ES6特性,而是希望尾部调用使用显式语法,如


另请参见:

从标题判断,您的真实代码中是否存在实际内存问题?顺便说一句,这不是泄漏,因为在函数结束后内存肯定会被清理。我没有内存问题,但我正在考虑使用这种方法实现一个函数。我知道当函数结束时内存会被释放,但是在实际函数结束之前,当处理一个或多个更深的调用时,它会释放内存吗?我认为这并不重要。堆栈帧将被保留,是的,因为V8仍然没有正确地实现尾部调用,但是为中间变量分配的内存将是可以忽略的。嗯,您不能假设这一点。我们不知道中间变量中包含的数据的大小。据我们所知,每次可能是500mb。但是你所说的关于V8没有正确实现尾部调用的内容是我感兴趣的。因此,如果GC需要更多内存,它不会释放所有以前的中间值?我强烈建议在问题中提及尾部调用或尾部递归。这可能被标记为一个dup