Node.js - Maximum call stack size exceeded

2019-01-04 17:58发布

When I run my code, Node.js throw "RangeError: Maximum call stack size exceeded" exception caused by too much recursion calls. I tried to increase Node.js stack-size by sudo node --stack-size=16000 app, but Node.js crash without any error message. When I run this again without sudo, then Node.js print 'Segmentation fault: 11'. Is there a possibility to solve this without removing recursion call?

Thanks

7条回答
别忘想泡老子
2楼-- · 2019-01-04 18:30

Please check that the function you are importing and the one that you have declared in the same file do not have the same name.

I will give you an example for this error. In express JS (using ES6), consider the following scenario:

import {getAllCall} from '../../services/calls';

let getAllCall = () => {
   return getAllCall().then(res => {
      //do something here
   })
}
module.exports = {
getAllCall
}

The above scenario will cause infamous RangeError: Maximum call stack size exceeded error because the function keeps calling itself so many times that it runs out of maximum call stack.

Most of the times the error is in code (like the one above). Other way of resolving is manually increasing the call stack. Well, this works for certain extreme cases, but it is not recommended.

Hope my answer helped you.

查看更多
Anthone
3楼-- · 2019-01-04 18:36

Regarding increasing the max stack size, on 32 bit and 64 bit machines V8's memory allocation defaults are, respectively, 700 MB and 1400 MB. In newer versions of V8, memory limits on 64 bit systems are no longer set by V8, theoretically indicating no limit. However, the OS (Operating System) on which Node is running can always limit the amount of memory V8 can take, so the true limit of any given process cannot be generally stated.

Though V8 makes available the --max_old_space_size option, which allows control over the amount of memory available to a process, accepting a value in MB. Should you need to increase memory allocation, simply pass this option the desired value when spawning a Node process.

It is often an excellent strategy to reduce the available memory allocation for a given Node instance, especially when running many instances. As with stack limits, consider whether massive memory needs are better delegated to a dedicated storage layer, such as an in-memory database or similar.

查看更多
Fickle 薄情
4楼-- · 2019-01-04 18:38

I found a dirty solution:

/bin/bash -c "ulimit -s 65500; exec /usr/local/bin/node --stack-size=65500 /path/to/app.js"

It just increase call stack limit. I think that this is not suitable for production code, but I needed it for script that run only once.

查看更多
闹够了就滚
5楼-- · 2019-01-04 18:45

In some languages this can be solved with tail call optimization, where the recursion call is transformed under the hood into a loop so no maximum stack size reached error exists.

But in javascript the current engines don't support this, it's foreseen for new version of the language Ecmascript 6.

Node.js has some flags to enable ES6 features but tail call is not yet available.

So you can refactor your code to implement a technique called trampolining, or refactor in order to transform recursion into a loop.

查看更多
对你真心纯属浪费
6楼-- · 2019-01-04 18:45

If you don't want to implement your own wrapper, you can use a queue system, e.g. async.queue, queue.

查看更多
Viruses.
7楼-- · 2019-01-04 18:45

I had a similar issue as this. I had an issue with using multiple Array.map()'s in a row (around 8 maps at once) and was getting a maximum_call_stack_exceeded error. I solved this by changing the map's into 'for' loops

So if you are using alot of map calls, changing them to for loops may fix the problem

查看更多
登录 后发表回答