代码之家  ›  专栏  ›  技术社区  ›  Kiyaan Pillai

为什么堆叠大小随功能而变化(V8发动机)?

  •  -2
  • Kiyaan Pillai  · 技术社区  · 2 年前

    我只是在尝试查看我的机器上的最大调用堆栈大小,我发现了一些非常奇怪的东西。我有以下两个功能:

    function fact(o) {
        if (o == 0) return 1;
        return o * fact(o - 1)
    }
    function k(o){
        if (o == 0) return;
        k(o - 1)
    }
    

    调用事实(9644)是在堆栈溢出之前我能得到的最高数字。例如,fact(9645)返回一个错误。

    但是,在堆栈溢出之前,我最多可以调用k(10448)。例如,k(10449)返回一个错误。

    我认为创建函数的方式可能会影响调用堆栈的大小。所以,我试着把事实变成一个常数箭头函数,并试着把它改成一个简单的三元求值,例如:

    const fact = (o) => o == 0 ? 1 : o * fact(o - 1);
    //OR
    function fact(o) {
        return o == 0 ? 1 : o * fact(o - 1);
    }
    

    在分配箭头函数时,我还尝试用let来分配它们,例如:

    let fact = (o) => o == 0 ? 1 : o * fact(o - 1);
    

    我用k做了类似的事情。无论我做什么,结果都是一样的。

    (如果重要的话,我会在Chrome Devtools控制台中运行它。)

    此外,经过研究,我得出结论,V8引擎不再进行任何尾部递归消除,所以我认为这也不是问题所在。但是,如果我错了,请纠正我。

    所以,我的问题是,有人能告诉我吗 为什么? 这是真的吗?

    1 回复  |  直到 2 年前
        1
  •  1
  •   Bergi    2 年前

    为什么堆栈大小因函数而异?

    因为不同的函数需要在堆栈上存储不同的东西。在您的示例中,第一个函数 fact 需要保持的价值 o 在递归调用中,第二个 k 没有。正常功能和箭头功能之间没有区别。

    堆栈大小通常以字节为单位(因为这就是内存分配的方式),而不是以堆栈帧数为单位。