I can't find any documentation about --stack-size=XXX node.js CLI parameter.
But this parameter seems to have some effect, increasing it to some value eliminates "stack overflow" error. But increasing it more further makes node.js unstable. (It just quits in some time without any error)
So my questions are:
Is XXX in bytes, kilobytes or megabytes?
What is the default value when this parameter is omitted?
What is the minimum and maximum possible values for this parameter?
How operating system (linux/windows) and platform (32bit/64bit) affects this parameter (maximum, minimum, default value)?
@euglv Please try looking at node --v8-options.
--stack_size (default size of stack region v8 is allowed to use (in kBytes))
In normal practice you shouldn't need to adjust this afaik, mind outlining what you are doing? It sounds like you may have recusing tail calls, which are not currently optimized by v8.
It's a v8 feature.
node --help:
…
--v8-options print v8 command line options
…
node --v8-options:
…
--stack_size (default size of stack region v8 is allowed to use (in kBytes))
type: int default: 984
…
Reopening, as I don't have info to answer the other questions, but other folks here might.
FWIW v8 5.0 (in node v6) has tail call optimizations behind a flag (--es-staging) if recursion is the issue here.
Note: it is still highly not recommended to use flagged features in production.
Thank you for answers.
So this is the only documentation about this option:
--stack_size (default size of stack region v8 is allowed to use (in kBytes))
type: int default: 984
Yes, cause of "stack overflow" error was recursion in my case. And I definitely need recursion, and recursion steps are definitely limited.
If I run node with --stack-size=1000 - still get "stack overflow" error, but fore some reason if I run node with --stack-size=1200 - in some step of a recursion node crushes silently, without any error at all.
When I searched internet about this issue I saw answers, that on linux node has one particular possiblestack-size limit, under windows - another.
No mention in documentation how large could be stack-size option, and on what it depends.
Finally I figured out how to get rid of "stack overflow" error, without touching stack-size option at all:
var recurciveFunc = function(params) {
/* Some code */
/* ..... */
setTimeout(function(){ recurciveFunc(params) }, 0);
}
If I wrap recursion call in setTimeout - "stack overflow" error disappears.
@euglv You could also use process.nextTick() or setImmediate() instead of setTimeout(..., 0)
@euglv
And I definitely need recursion
Just a reminder: any recursion could be converted to an iterative algorithm. So you probably don't. :wink:
--stack_size controls what V8 _thinks_ is the stack size, not the actual stack size. It's for overriding the default when the default doesn't match reality. V8's estimate is fairly conservative, there is normally no need to touch it.
If you set it higher than the actual limit, the process gets killed (on UNIX) by a SIGBUS signal when it exceeds the limit.
I'll close, I think that answers the question.
@bnoordhuis Would you mind answering how we can determine the "actual stack size"? Is this simply the unused heap? Or some other machine characteristic? We are considering modifying the stack_limit, but we want to be sure that the change will be stable in production. Thank you.
@louisbuchbinder You might need to talk to your OS for that; if it’s about Linux and maybe other POSIXes, ulimit -s should be helpful.
Oh interesting thank you for the quick response!
One more question here. Is there any way to get/print the value of the stack_size option during runtime? In the v8 docs I can see a method to set options from a string, but no mention of getting that value. I am using node6. Thank you!
@louisbuchbinder
$ node --v8-options | grep -A1 -w stack_size
--stack_size (default size of stack region v8 is allowed to use (in kBytes))
type: int default: 984
looks like a good requirement for node-report
==== Node Report =======================================================
Event: SIGUSR2, location: "SignalDumpInterruptCallback"
Filename: node-report.20170517.125940.57943.001.txt
Dump event time: 2017/05/17 12:59:40
Module load time: 2017/05/17 12:57:49
Process ID: 57943
Thread stack size: 8092M >> new
Command line: node -r node-report --stack_size=8286208 --max-old-space-size=200 cpu.js
Node.js version: v7.10.0
(ares: 1.10.1-DEV, cldr: 30.0.3, http_parser: 2.7.0, icu: 58.2, modules: 51,
openssl: 1.0.2k, tz: 2016j, unicode: 9.0, uv: 1.11.0, v8: 5.5.372.43, zlib: 1.2.11)
/cc @ rnchamberlain
@bnoordhuis Thank you, but I am trying to print the current value in the process that I have updated. Unfortunately I do not have control of the invocation of my script (that is done by our platform helper process). I am looking for a way to confirm/test that the value I expect to see has actually been updated. It looks like @gireeshpunathil might be on to something with node-report, however I am unfamiliar with that tool.
@louisbuchbinder You cannot, not reliably. You could scan process.execArgv but that won't help if the application calls v8.setFlagsFromString('--stack_size=1234').
@bnoordhuis - correct me if I am missing something: a call to pthread_attr_getstacksize is all what is required to get it right? Is it that not all the threads in the process obey --stack_size? or are there other reasons?
@gireeshpunathil See https://github.com/nodejs/node/issues/11091#issuecomment-283007063.
o! thanks. I never thought that was what --stack_size is. So the actual thread stack size is different and is controlled natively, while this controls some V8's internal structure for managing code size, method calls etc.
So agree, that measuring the value this flag neither is reliable, nor meaningful.
Most helpful comment
@louisbuchbinder You might need to talk to your OS for that; if it’s about Linux and maybe other POSIXes,
ulimit -sshould be helpful.