浏览器Javascript堆栈大小限制


75

我在IE浏览器中遇到了一些客户端Javascript堆栈溢出问题,这是在第三方库中发生的,该第三方库进行了一些函数调用,并且由于某些原因,它们有时仅由于IE堆栈限制低而在IE中制动。

然后,我编写了一个小的测试HTML,以测试某些浏览器的堆栈大小限制,发现与运行Windows 7 OS,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
3200个调用有足够的堆栈空间。Python程序员(嗯,那些不愿意写递归下降解析器或用递归代替完美的简单循环的程序员)相处很好,并且调用限制为1000。你在做什么?

4
它不是用疑问词强硬地措词,但最后一句话“我想知道是否有……”可以以“ Are there”开头,以问号结尾,从而产生一个相当直接的问题。
jball 2011年

感谢您的反馈,我将更好地阐明问题
guilhebl 2011年

Answers:


129

使用一个简单的测试:

var i = 0;
function inc() {
  i++;
  inc();
}
    
try {
  inc();
}
catch(e) {
  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

谷歌浏览器

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

苹果浏览器

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

歌剧

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

边缘

  • 87:13970

关于您的问题,请使用浏览器的开发人员工具查看堆栈。在IE 8+中,单击F12,转到“脚本”选项卡,然后单击“开始调试”。当引发异常时,它将中断,您可以看到调用堆栈。您也可以使用Chrome的开发人员工具Ctrl+ Shift+ J


7
您也可以在Chrome上使用F12
Juan Mendes

1
通过测试jsfiddle.net/9YMDF/show,我在Chrome 28上具有〜21000,在Firefox 20+上具有26000..53000,在Windows 7 SP1 64位上具有IE10〜3000。Opera 12.X的堆栈深度非常接近32768。我发现一个不幸的IE8安装,堆栈深度等于276!
维克多

您可以将这些结果与此处链接的BrowserScope
Janus Troelsen

这使我在Microsoft Edge上获得151102,而在IE11上获得了54375!
Gaurav Ojha

5
我认为数字不是映射到浏览器,而是映射到应用程序当前保留的内存。因此,答案差异很大。对于为例,E我只是跑了测试,我得到20922为Chrome 56(有很多扩展),以及8921一个相当普通的香草火狐49.一个绝对股价优势的浏览器,我得到16615.
罗伯特·托马斯

7

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


TCO真的是用JavaScript完成的吗?我了解到ES6可能会获得支持,但我认为它尚未实现。
Janus Troelsen

TCO目前在chrome中是一个标志(正在评估两种不同的实现)。我不知道默认情况下已实现该功能的任何浏览器。
Jethro Larson

1
@JanusTroelsen:ES2015(“ ES6”)确实确实需要发动机进行TCO。V8拥有它,但是V8团队还不认为它“稳定”,因此必须启用它。(V8将它们已经开始的功能归类为“发货”,“完成”,“稳定”和“进行中”。TCO仍为“进行中”,但V8的所有三个代码生成器都有其基础。我认为它们尚未将其提升为“稳定”状态,因为它们仍在优化/错误查找/错误修复。更多信息:stackoverflow.com/a/30369729/157247
TJ Crowder

目前,Safari仅是具有适当TCO的浏览器
ridderhoff

一个用例“把大量的东西放到堆栈上”array1.push(...array2)比用array1 = array1.concat(array2)数组2太长要快得多,但会抛出“超出最大堆栈大小”。看到这里
Mila Nautikus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.