nodejs / help

:sparkles: Need help with Node.js? File an Issue here. :rocket:
1.45k stars 278 forks source link

JavaScript heap out of memory with use of regular expressions #4233

Closed Cooya closed 3 months ago

Cooya commented 11 months ago

Details

I have been struggling for quite some time with app crashes due to regular expressions. The error is the following :

<--- Last few GCs --->

[1685552:0x75ea280]   314137 ms: Mark-sweep (reduce) 275.3 (309.7) -> 275.3 (306.7) MB, 129.1 / 0.0 ms  (average mu = 0.128, current mu = 0.115) last resort; GC in old space requested
[1685552:0x75ea280]   314266 ms: Mark-sweep (reduce) 275.3 (306.7) -> 275.3 (306.7) MB, 128.8 / 0.0 ms  (average mu = 0.067, current mu = 0.001) last resort; GC in old space requested

<--- JS stacktrace --->

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: 0xb83f50 node::Abort() [SCRIPT]
 2: 0xa94834  [SCRIPT]
 3: 0xd647c0 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [SCRIPT]
 4: 0xd64b67 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [SCRIPT]
 5: 0xf3039f v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [SCRIPT]
 6: 0xf10338 v8::internal::Factory::CodeBuilder::AllocateCode(bool) [SCRIPT]
 7: 0xf2427c v8::internal::Factory::CodeBuilder::BuildInternal(bool) [SCRIPT]
 8: 0xf24d1e v8::internal::Factory::CodeBuilder::Build() [SCRIPT]
 9: 0x15de69e v8::internal::RegExpMacroAssemblerX64::GetCode(v8::internal::Handle<v8::internal::String>) [SCRIPT]
10: 0x12a3186 v8::internal::RegExpCompiler::Assemble(v8::internal::Isolate*, v8::internal::RegExpMacroAssembler*, v8::internal::RegExpNode*, int, v8::internal::Handle<v8::internal::String>) [SCRIPT]
11: 0x12c30c7 v8::internal::RegExpImpl::Compile(v8::internal::Isolate*, v8::internal::Zone*, v8::internal::RegExpCompileData*, v8::base::Flags<v8::internal::RegExpFlag, int>, v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::String>, bool, unsigned int&) [SCRIPT]
12: 0x12c3842 v8::internal::RegExpImpl::CompileIrregexp(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSRegExp>, v8::internal::Handle<v8::internal::String>, bool) [SCRIPT]
13: 0x12c43fe v8::internal::RegExpImpl::IrregexpPrepare(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSRegExp>, v8::internal::Handle<v8::internal::String>) [SCRIPT]
14: 0x12c45a3 v8::internal::RegExpImpl::IrregexpExec(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSRegExp>, v8::internal::Handle<v8::internal::String>, int, v8::internal::Handle<v8::internal::RegExpMatchInfo>, v8::internal::RegExp::ExecQuirks) [SCRIPT]
15: 0x12e993e v8::internal::Runtime_RegExpExec(int, unsigned long*, v8::internal::Isolate*) [SCRIPT]
16: 0x17035b9  [SCRIPT]

I have tried to set NODE_OPTIONS="--max-old-space-size=2048" but it has no effect. My script is using dozens of regular expressions, some of them are quite complex, but I cannot put a finger on the one that triggers the memory crash and I am not sure there is one regular expression in particular causing the issue. I tried to wrap the methods related to regular expressions (new RegExp, RegExp.exec(), String.match(), String.matchAll(), String.replace() and String.split()) to log the last regular expression used before the process crashes, but nothing conclusive. I tried as well to simplify the more complex regular expressions in my code, but the issue is still persisting. The crash is hard to reproduce as it happens every few hours of running in production.

Any idea on how to determine the origin of the issue ?

Node.js version

v18.17.0

Example code

No response

Operating system

Ubuntu 20.04.5 LTS

Scope

Not applicable.

Module and version

Not applicable.

preveen-stack commented 11 months ago

Can you share example code to reproduce the crash @Cooya

Cooya commented 11 months ago

I wish I could reproduce the crash.

preveen-stack commented 11 months ago

PTAL #4178

preveen-stack commented 11 months ago

Also check https://github.com/nodejs/help/issues/3425. There is a link to a stack overflow ticket on that issue which lists out some approaches

preveen-stack commented 11 months ago

reference: https://www.regular-expressions.info/catastrophic.html

Cooya commented 11 months ago

Thank you for your help.

I am starting to think the issue has nothing to do with regular expressions but it is more of a NodeJS problem. When the crash occurs, the heap size is about 300MB whereas the maxium heap size is about 4GB. It should not trigger a out of memory error because the process has still plenty of space in the heap.

At the end of last July, I upgraded my version of NodeJS from 18.16 to 18.17 and I wonder if the issue did not start to occur after this upgrade. I am trying a downgrade to 18.16 to see if the process stops crashing.

preveen-stack commented 11 months ago

Okay. Please take a look at change log https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V18.md#18.17.1

github-actions[bot] commented 3 months ago

It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.

Cooya commented 3 months ago

The issue has been resolved with the upgrade to NodeJS v20.11.0.