浏览器 Javascript 堆栈大小限制

IT技术 javascript browser stack limit
2021-01-29 20:13:59

我在 IE 浏览器中遇到了一些客户端 Javascript 堆栈溢出问题,这是在第三方库中发生的,该库进行了一些函数调用,出于某种原因,它们偶尔会在 IE 中刹车,只是因为它的堆栈限制较低。

然后我编写了一个小的测试 HTML 来测试某些浏览器的堆栈大小限制,发现与在 Windows 7 操作系统、8Gb RAM 的笔记本电脑上运行的 FF 7 或 Chrome 14 相比,IE8 实际上有一个小的堆栈限制:

<html>
<body>

<!-- begin Script: -->
<script type="text/javascript">

function doSomething(){

  var i = 3200;
  doSomethingElse(i);

}

function doSomethingElse(i){
  if (i == 0) return -1;
  doSomethingElse(i-1);
}

doSomething(); 

</script>
<!-- END OF PAGE -->

</body>
</html>

当值在 3200 左右时 IE 会引发堆栈溢出,如果与 IE 相比,Firefox 和 Chrome 可以处理非常深的递归。

我想知道是否有办法将堆栈溢出异常与在 IE 或任何其他浏览器中运行时引发它的 Javascript 函数联系起来,以及它是否可以在堆栈中提供带有函数链的堆栈跟踪错误被提出。

2个回答

使用一个简单的测试:

var i = 0;
function inc() {
  i++;
  inc();
}
    
try {
  inc();
}
catch(e) {
  // The StackOverflow sandbox adds one frame that is not being counted by this code
  // Incrementing once manually
  i++;
  console.log('Maximum stack size is', i, 'in your current browser');
}

IE浏览器

  • IE6:1130
  • IE7:2553
  • IE8:1475
  • IE9:20678
  • IE10:20677

火狐浏览器

  • 3.6:3000
  • 4.0:9015
  • 5.0:9015
  • 6.0:9015
  • 7.0:65533
  • 8b3:63485
  • 17:50762
  • 18:52596
  • 19:52458
  • 42:281810
  • 89:10746
  • 91:26441

谷歌浏览器

  • 14:26177
  • 15: 26168
  • 16:26166
  • 25:25090
  • 47:20878
  • 51:41753
  • 93:13903

苹果浏览器

  • 4:52426
  • 5:65534
  • 9:63444
  • 14:45606

Safari iOS

  • 15: 7909

歌剧

  • 10.10:9999
  • 10.62:32631
  • 11: 32631
  • 12: 32631
  • 78:13908

边缘

  • 87:13970
  • 93:13903

Yandex

  • 21: 13909

关于您的问题,请使用浏览器的开发人员工具查看堆栈。在 IE 8+ 中,点击F12,转到脚本选项卡,然后单击开始调试。抛出异常就会break,可以看到调用栈。您还可以使用 Chrome 的开发人员工具Ctrl+ Shift+ J

您可以将这些结果与此处链接的 BrowserScope进行比较
2021-03-15 20:13:59
这在 Microsoft Edge 上为我提供了 151102,而在 IE11 上为 54375!
2021-03-18 20:13:59
使用jsfiddle.net/9YMDF/show测试,Chrome 28 为 21000,Firefox 20+ 为 26000..53000,Windows 7 SP1 64 位上的 IE10 为 3000。Opera 12.X 的堆栈深度接近 32768。而且我发现了一个不幸的 IE8 安装,堆栈深度等于 276!
2021-03-19 20:13:59
你也可以在 Chrome 上使用 F12
2021-03-26 20:13:59
我认为这些数字不会映射到浏览器,而是映射到应用程序当前保留的内存因此,答案千差万别。例如,我刚刚运行了那个测试,我在 Chrome 56(有很多扩展)上得到了 20922,在一个相当普通的 Firefox 49 上得到了 8921。有了一个绝对正常的边缘浏览器,我得到了 16615。
2021-03-28 20:13:59

这是特定于浏览器的,不仅是堆栈大小,还有优化,比如尾递归优化之类的东西。我想这里唯一可靠的事情是以一种不会将大量内容放入堆栈的方式进行编码,或者手动测试(深入阅读)每个浏览器的文档。毕竟,当您看到“递归过多”错误或类似错误时,您就已经知道您的代码确实有问题。

TCO 现在是 chrome 中的一个标志(正在评估两种不同的实现)。我不知道有任何浏览器默认实现了它。
2021-03-11 20:13:59
目前 safari 是唯一具有适当 TCO 的浏览器
2021-03-15 20:13:59
@JanusTroelsen:ES2015(“ES6”)确实需要引擎来实现 TCO。V8 有它,但 V8 团队并不认为它“稳定”,所以你必须启用它。(V8 将他们已经开始的功能分类为“交付”[完成]、“稳定”和“进行中”。TCO 仍然“进行中”,但 V8 的所有三个代码生成器的基础知识都在那里。我认为他们尚未将其提升为“稳定”,因为他们仍在优化/错误查找/错误修复。更多信息:stackoverflow.com/a/30369729/157247
2021-03-16 20:13:59
“将大量内容放在堆栈上”的一个用例array1.push(...array2)array1 = array1.concat(array2)当 array2 太长时抛出“超出最大堆栈大小”要快得多这里
2021-03-30 20:13:59
TCO 真的是用 JavaScript 完成的吗?我读过 ES6 可能会得到支持,但我认为它还没有实现。
2021-04-10 20:13:59