【发布时间】:2020-08-06 00:20:31
【问题描述】:
除了--stack-size 选项之外,还有其他方法可以限制 NodeJS 中递归的深度吗?
我知道 NodeJS 会让你通过 --stack-size 选项控制调用堆栈的大小。即这样的程序
const recurse = (num=0) => {
context.num++
recurse(++num)
}
const context = {
num:0
}
try {
recurse(context)
} catch(e) {
console.log('Took ' + context.num + ' trips before bailing')
}
默认会输出这样的东西。
$ node so.js
Took 12530 trips before bailing
但是,您可以使用--stack-size 告诉节点您希望在退出之前让堆栈达到多大(以 kb 为单位)。使用更大的堆栈,你会得到更多的递归。
$ node --stack-size=5000 so.js
Took 63935 trips before bailing
--stack-size 选项是 Node 的 V8 选项之一。您可以通过运行node --v8-options 查看所有这些选项的列表。
我想知道的是 NodeJS 中是否有一种方法可以将递归深度显式限制为某个特定数字。
我在这里没有具体的最终目标——我只是想了解 NodeJS 与我工作过的其他语言相比有哪些工具,哪些工具没有。如果 node 没有也可以这个——我只是在这里学习:)
【问题讨论】:
-
作为参考,同一个人关于此主题的上一个问题:Nodjs and CallStack Size Protection。
-
理论上,您可以计算出所有堆栈帧的大小并乘以您希望允许的数量,但是应该触发各种XY problem 警报。我知道你声称自己没有目标,但问题仍然存在:为什么?
-
@ggorlen 好问题。我从事开发工具方面的工作,通常我喜欢了解我的运行时在做什么。这绝对不是 95% 的人所需要的。之所以出现这些特定系列的问题,是因为我们发现了一些意外无限递归错误的情况,但 --stack-size 并没有拯救我们。我发现有一个功能说“嘿,如果这是堆栈深度为 1000 次调用,我们可能应该崩溃,因为出现严重错误”很有用。
-
@ggorlen 很高兴在其他地方继续这个对话,但是当你说“你不应该吃掉这么多堆栈内存”时,这并没有考虑堆栈不增长的递归场景。在等待后执行返回到函数时,V8 调用堆栈不包含先前的递归调用。即调用堆栈没有增长,但递归将继续。这种递归可能会导致其他问题,并且是不明显的。用户空间递归深度的理论限制可以很好地解决这个问题。
-
当然,看起来你不能只除以调用大小。我没有答案,可能只是占用空间——祝你好运!
标签: node.js recursion callstack