Looking at Task Manager I see memory usage of my node.js process increasing continuously - so a memory leak. I'm implementing a loop via recursion, could this be the cause?
The code below does the following:
- extracts about 64KB from a flatfile via a generator function into the
batch
variable - batches consist of lines - each line is retrieved from the 64kb batch iteratively
- each line has x number of transformations applied to it
- Each batch is sent over the network
Is it possible that the batch
variable is waiting until the recursive chain resolves before being cleaned up by the GC?
await (async function nextBatch() {
const batch = batches.next();
const payload = [];
if (batch.done) return;
const values = batch.value;
await asyncForEach(values, async(item) => {
await asyncForEach(transformations, async(t) => {
item = await t.transform.call(t, item);
});
if (item !== {} && item) payload.push(item);
});
const loadResult = await load.batch(payload);
await nextBatch();
})();
I get the following error:
<--- Last few GCs --->
[21760:0000020D47008EF0] 935709 ms: Mark-sweep 1406.7 (1472.4) -> 1406.5 (1444.4) MB, 380.6 / 0.0 ms (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 381 ms) last resort GC in old space requested
[21760:0000020D47008EF0] 936051 ms: Mark-sweep 1406.5 (1444.4) -> 1406.5 (1444.4) MB, 341.2 / 0.0 ms last resort GC in old space requested
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 000002D779C25EE1 <JSObject>
2: new constructor(aka Parser) [C:\MSc\Thesis\netl\node_modules\csv-parse\lib\index.js:167] [bytecode=000002935CBD0F09 offset=452](this=0000014FD4695319 <Parser map = 000001D4E8BB1749>,/* anonymous */=0000034EC0F9C829 <Object map = 000001D4E8BAB341>)
5: /* anonymous */ [C:\MSc\Thesis\netl\node_modules\csv-parse\lib\sync.js:20] [bytecode=000002935CBD0599 offset=114](this=0000011FD4F8BF9...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node_module_register
2: v8::internal::FatalProcessOutOfMemory
3: v8::internal::FatalProcessOutOfMemory
4: v8::internal::Factory::SetClassFunctionInstanceDescriptor
5: v8::internal::Factory::NewFunction
6: v8::internal::Factory::NewFunctionFromSharedFunctionInfo
7: v8::internal::Factory::NewFunctionFromSharedFunctionInfo
8: v8::internal::compiler::Pipeline::AllocateRegistersForTesting
9: 00000362273847A1