在浏览器中增加堆栈大小

6
短问题:我有一个递归很深的javascript。如何增加堆栈大小以便我可以执行它(类似于Unix系统中的“ulimit -s unlimited”)?
长话短说:我需要绘制一个图形,我使用Cytoscape JS(http://js.cytoscape.org/)与Dagre布局扩展程序(https://github.com/cytoscape/cytoscape.js-dagre)配合使用。绘图算法在递归中深入,结果在Chrome中出现“Uncaught RangeError:Maximum call stack size exceeded”,在Firefox中出现“too much recursion”。如何将堆栈大小设置为无限或非常大(即像Unix系统中的“ulimit -s unlimited”那样),以便我可以绘制图形?
谢谢!

你确定你的算法是正确的吗?你有计算在你超出堆栈空间时嵌套调用的次数吗?这个数字合理吗? - trincot
是的,算法是正确的。问题在于图形有点大,绘图算法会深度递归。然而,使用其他绘图算法(不使用递归),我能够相当快地绘制它...所以我想如果我可以增加堆栈大小到一个相当大的大小,我就能够绘制它。我搜索了一下,但没有找到任何答案...最坏的情况下,我需要修改Dagre算法,将其从递归改为迭代...但我想检查一下是否有任何方法设置浏览器的javascript引擎的堆栈大小限制。 - iwicopd2
1
添加更多上下文,您可以在此找到几个浏览器的堆栈大小限制:https://dev59.com/0Wsz5IYBdhLWcg3wiYY0?rq=1。我只需要增加这个限制。 - iwicopd2
你能报告一下在内存耗尽之前你所处的嵌套调用次数吗? - trincot
你好。我正在使用第三方库,其中有几个函数进行了深度递归。其中一个函数递归了大约3000层,但是对于我来说改变整个库是不切实际的。目前我有一个解决方法,它涉及到通过调用带有--js-flags="--stack_size x"命令行参数的Google Chrome来更改堆栈大小,x很大。非常感谢您的帮助。 - iwicopd2
3个回答

2
Chrome有一个标志用于此操作:

chromium-browser --js-flags="--stack-size 2048"

在执行上述命令之前,您还需要运行ulimit -s unlimited,否则,您的深度递归JavaScript代码将会导致Chrome崩溃。


可用的 V8 标志可以使用 --js-flags="--help" 查找。 - mikwat

0

尝试更改您的算法,以便在每次函数迭代时不使用太多堆栈空间。例如:

  • 当未使用本地变量时将其设置为null。
  • 在可能的情况下,使用全局变量进行临时计算。这样,该临时变量就不会在堆栈上。
  • 在递归函数中使用较少的变量。在函数的不同部分中,为不同的事物重复使用相同的变量。
  • 将递归函数分解成几个函数。其中一些函数不会是递归的,因此这些函数中的本地变量在递归函数调用自身时不会继续存在。
  • 创建一个全局数组来执行任务,并向该列表添加项目,而不是递归调用函数。使用array()对象的push和pop方法。
  • 在递归函数中使用较少的参数。传递一个对象。

希望这些想法能对您有所帮助。


你好。感谢您的回答。我已经考虑了其中一些事情,但是您的列表确实更完整!但是,如果我尽可能地减少每个函数调用时的堆栈空间,但算法本身在递归中深入得太深,而我无法改变为迭代算法呢?也就是说,我真的需要增加堆栈大小吗?我不能在现代浏览器中做到这一点吗?因此,我应该将我的脚本重新编码为桌面应用程序,以便能够拥有大的堆栈大小吗? - iwicopd2
我曾在Windows中使用C进行编程,有一个非常大的二叉树。我编写了一个递归函数,在函数完成后删除该树。但是,这个递归函数会崩溃。我不得不将递归函数重写为迭代函数。我认为更改语言或扩展堆栈都无法解决您的算法问题。如果您将堆栈大小加倍或三倍,您可能仍然会遇到相同的问题。 - Russell Hankins
你好。我正在使用第三方库,其中有几个函数递归深度很大。对于我来说,改变整个库是不切实际的。我也同意并更喜欢迭代而不是递归编写代码,但有时递归在算法上更加清晰。在UNIX系统中,有时我们会遇到这种情况,ulimit -s unlimited可以解决问题。目前我有一个js的解决方法,涉及通过调用带有--js-flags="--stack_size x"命令行参数的Google Chrome来更改堆栈大小,x很大。非常感谢您的帮助。 - iwicopd2
在dagre存储库中发布Github问题是个好主意,因为递归就发生在那里: https://github.com/cpettitt/dagre - maxkfranz

-1

问题是“如何将堆栈大小设置为无限或非常大?” 这并没有回答问题。 - Clément
@Clément...即使它被选为接受的答案?? :O 这个答案意味着这是不可能的,只是没有明确说明。 - Erik Kaplun
感谢您的编辑。您确定这是不可能的吗?OP在评论中提到的标志似乎确实增加了堆栈大小(虽然无法从JavaScript实现该效果,但仍可从命令行中使用)。 - Clément

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接