Search code examples
node.jsv8

Setting --max-old-space-size but Node still exceeds the limit without causing any errors


I set a max size to 512mb but it doesn't seem to cause any error and it exceeds the limit and goes up 1.3GB. I understand that node will try to GC when it approaches the limit and error out when it exceeds the set limit. I'm running tests and I want it to not exceed 512mb limit.

OS: Ubuntu 20.04.2 LTS
NODE VERSION : 10.19.0

node --max-old-space-size=512 Server.js

Solution

  • I just need to know if that's a normal behavior

    No, it's not.

    It makes the flag pointless.

    With a simple demo program, the flag works as expected:

    $ cat demo.js
    let big = [];
    while (true) {
      big.push(new Array(10000));
    }
    
    $ node --version
    v16.3.0
    $ node --max-old-space-size=512 demo.js 
    
    <--- Last few GCs --->
    
    [20343:0x563cd38c25a0]     1112 ms: Mark-sweep 477.8 (523.7) -> 477.5 (525.7) MB, 158.4 / 0.0 ms  (average mu = 0.124, current mu = 0.011) allocation failure scavenge might not succeed
    
    
    <--- JS stacktrace --->
    
    FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
     1: 0x563ccf1a6680 node::Abort() [node]
     2: 0x563ccf0b28e9 node::FatalError(char const*, char const*) [node]
     3: 0x563ccf332082 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
    ...
    

    Note that Node's command-line flag parsing is order-dependent. E.g. if you run node demo.js --max-old-space-size=512, then the flag won't apply to the execution of demo.js.


    If that doesn't answer your question, then please state more clearly what you measured. For example, if you looked at the overall memory usage of the process, that would be expected to be larger than 512MB, because the "old space" is just part of what's in the process -- it's the part that's most controllable. Depending on what your app does, there can be other consumers of memory. While I would find an extra 800MB surprising, anything's possible as long as you don't provide a repro, or more details on what you measured and how.