A 4-minute primer to memory management and garbage collection in Node.js

Node.js manages memory using different memory spaces.

In this article, we will learn in under 4 minutes what the different spaces are, how they relate to each other and what it means when your Node.js script throws a FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory.

So let's get started!

The different memory spaces

Nodes.js uses two main memory spaces to store function calls, primitive values, and objects in memory: stack memory and heap memory:

Stack memory

Stack memory or "the stack" is used for storing function calls, local variables, and control flow in so called stack frames.

When a function completes, a program ends or an exception unwinds the stack, the stack memory is freed again.

Objects are not stored in stack memory. Stack memory only contains references to objects. The objects themselves are stored in heap memory.

Heap memory

Heap memory or "the heap" is memory allocated for objects.

Heap memory is divided into a "new space" and an "old space":

The "new space" is further subdivided into two equally sized semi-spaces: the "from space" and the "to space":

When objects are created, they are added to the "from space" in the "new space".

Newly created objects are added to the "from space" in the "new space".

When the "from space" is full, garbage collection is triggered inside the "new space".

Garbage collection in the "new space" is a fast and frequent process. Objects that are still referenced in your application are copied from the "from space" to the "to space":

When garbage collection runs in the "new space", objects that are still referenced are copied from the "from space" to the "to space" within the "new space".

The "from space" is then emptied and the "to space" and "from space" are swapped.

Objects that survive multiple garbage collections in the "new space" are moved to the "old space".

When objects survive multiple garbage collections in the "new space", they are moved to the "old space".

When garbage collection runs in the "old space", objects that are no longer referenced in your application are selectively removed from the "old space":

When objects are no longer referenced, they are removed from the "old space" during garbage collection in the "old space".

Garbage collection in the "old space" is less frequent but more intensive.

When the "old space" is full, a FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory is thrown:

<--- Last few GCs --->
ze[59239:0x148008000]      
462 ms: Mark-Compact (reduce) 15.3 (16.8) -> 15.1 (17.3) MB, 0.88 / 0.00 ms  (+ 0.3 ms in 7 steps since start of marking, biggest step 0.1 ms, walltime since start of marking 4 ms) (average mu = 0.754, current mu = 0.737) finalize[59239:0x148008000]      
468 ms: Mark-Compact (reduce) 15.9 (17.5) -> 15.3 (17.5) MB, 3.21 / 0.00 ms  (+ 0.3 ms in 8 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 5 ms) (average mu = 0.551, current mu = 0.398) allocati

<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

Phew, that was a lot, so let's summarize what we learned.

Summary

Nodes.js uses two main memory spaces to store function calls, primitive values, and objects in memory: stack memory and heap memory.

Stack memory or "the stack" is used for storing function calls, local variables, and control flow in so-called stack frames.

When a function completes, a program ends or an exception unwinds the stack, the stack memory is freed again.

Objects are not stored in stack memory but in heap memory.

Heap memory is divided into a "new space" and an "old space".

Garbage collection in the "new space" is frequent and very fast.

When objects survive multiple garbage collections in the "new space", they are moved to the "old space".

Garbage collection in the "old space" is less frequent and very intense.

When the "old space" is full, a FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory is thrown.

That's itβ€”you made it, congratulations! πŸŽ‰

When you now receive a memory error in Node.js, you'll be able to understand what's happening and why! πŸŽ‰

Happy coding! πŸ™ πŸ™‡β€β™‚οΈ