首页 > 解决方案 > WebKit 中的最大调用栈大小是 V8 的三倍吗?为什么?

问题描述

我从这篇博客文章中看到以下函数来计算最大调用堆栈大小:

function computeMaxCallStackSize() {
    try {
        return 1 + computeMaxCallStackSize();
    } catch (e) {
        // Call stack overflow
        return 1;
    }
}

如果从 Chrome 的控制台运行,12530结果是(对于 V8)

假设相同的函数为 WebKit 计算相同的结果,为什么当为 Safari 运行时是36243结果?这是〜三倍的大小?我遇到这个错误的唯一一次是在创建一个好的 ole 无限循环时。这是一个武断的决定吗?更大的堆栈大小会带来更大的好处吗?

标签: memorystackwebkitv8

解决方案


(递归与否,无关紧要)调用的最大数量由 (1) 可用堆栈空间的大小除以 (2) 活动函数的每个堆栈帧的大小确定。

(1) 有操作系统规定的上限;在我知道的系统上,它通常在 1MB 到 8MB 之间。低于该限制,JavaScript 引擎可以设置自己的限制。V8 在所有平台上都设置了小于 1 MB 的限制,以使不同平台的行为尽可能地相似。我不知道 Safari/JavaScriptCore 做了什么。

(2) 取决于 JavaScript 引擎的实现细节(具体来说,它用于内部数据的每个堆栈帧中有多少个槽),以及涉及的每个函数中的局部变量的数量。

正如您所观察到的,通常只有在意外无限递归的情况下才会遇到堆栈限制。所以对于大多数实际应用程序来说,限制的具体值并不重要,更大的堆栈没有任何好处。

请注意,堆栈空间与最大内存消耗(也称为堆空间)无关。您可以拥有千兆字节的堆,而只有 1 兆字节的堆栈。


推荐阅读