我从this博客上看到以下函数来计算最大调用堆栈大小:
function computeMaxCallStackSize() {
try {
return 1 + computeMaxCallStackSize();
} catch (e) {
// Call stack overflow
return 1;
}
}
如果从Chrome的控制台运行,12530
就是结果(对于V8)
假设相同的函数为WebKit计算相同的结果,为什么在为Safari运行时36243
结果呢?这是大小的三倍?我遇到这个错误的唯一一次是创建一个好的无限循环。这是一个武断的决定吗?更大的堆栈大小会带来更大的好处吗?
(递归或不重要)调用的最大数量由(1)可用堆栈空间的大小除以(2)活动函数的每个堆栈帧的大小来确定。
(1)具有操作系统规定的上限;在系统上我知道它通常在1MB到8MB之间。低于该限制,JavaScript引擎可以设置自己的限制。 V8在所有平台上设置小于1兆字节的限制,以使不同平台的行为尽可能彼此相似。我不知道Safari / JavaScriptCore做了什么。
(2)取决于JavaScript引擎的实现细节(具体来说,它用于内部数据的每个堆栈帧中有多少个槽),以及所涉及的每个函数中的局部变量的数量。
正如您所观察到的,在意外无限递归的情况下,通常只会遇到堆栈限制。因此,对于大多数实际应用程序,限制的特定值无关紧要,更大的堆栈不会带来任何好处。
请注意,堆栈空间与最大内存消耗(即堆空间)无关。只有一兆字节的堆栈就可以有几千兆字节的堆。