当我运行我的代码时,Node.js抛出了一个"RangeError: Maximum call stack size exceeded"
异常,这是由过多的递归调用引起的。我试图通过sudo node --stack-size=16000 app
来增加Node.js堆栈的大小,但是Node.js崩溃了,没有任何错误消息。当我不使用sudo再次运行此命令时,Node.js将打印'Segmentation fault: 11'
。有没有可能在不删除递归调用的情况下解决这个问题?
发布于 2014-01-06 06:32:30
我找到了一个肮脏的解决方案:
/bin/bash -c "ulimit -s 65500; exec /usr/local/bin/node --stack-size=65500 /path/to/app.js"
它只会增加调用堆栈限制。我认为这不适合于产品代码,但我需要它用于只运行一次的脚本。
发布于 2014-01-06 01:29:40
在一些语言中,这可以通过尾部调用优化来解决,其中递归调用在幕后转换为循环,因此不存在最大堆栈大小达到的错误。
但是在javascript中,当前的引擎并不支持这一点,预计新版本的Ecmascript 6语言也会支持。
Node.js有一些启用ES6功能的标志,但尾部调用尚不可用。
因此,您可以重构代码以实现一种称为trampolining的技术,或重构以实现transform recursion into a loop。
发布于 2019-11-18 13:17:28
前置:
对我来说,使用Max调用堆栈的程序并不是因为我的代码。这最终是一个不同的问题,导致了应用程序流中的拥塞。因此,因为我试图在没有任何配置机会的情况下向mongoDB添加太多项,所以出现了调用堆栈问题,我花了几天时间才弄清楚是怎么回事,on....that说:
接着@Jeff Lowery回答道:我非常喜欢这个答案,它至少将我正在做的事情的进程加快了10倍。
我是编程新手,但我尝试将答案模块化。另外,我不喜欢抛出错误,所以我把它包装在一个do while循环中。如果我做错了什么,请随时纠正我。
module.exports = function(object) {
const { max = 1000000000n, fn } = object;
let counter = 0;
let running = true;
Error.stackTraceLimit = 100;
const A = (fn) => {
fn();
flipper = B;
};
const B = (fn) => {
fn();
flipper = A;
};
let flipper = B;
const then = process.hrtime.bigint();
do {
counter++;
if (counter > max) {
const now = process.hrtime.bigint();
const nanos = now - then;
console.log({ 'runtime(sec)': Number(nanos) / 1000000000.0 });
running = false;
}
flipper(fn);
continue;
} while (running);
};
看看这篇文章的要点,看看我的文件以及如何调用循环。https://gist.github.com/gngenius02/3c842e5f46d151f730b012037ecd596c
https://stackoverflow.com/questions/20936486
复制相似问题