Home

Heap out of memory

#learning #node

30th of April 2021


Well, that was a long and scary-looking error. The log boiled down to

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

The application ran out of memory when it was being built. Node.js has some implemented memory limits to prevent the application to consume too much memory. How high is the limit available to you, is dependant on the version of Node that you use and on your system’s architecture (32-bit or 64-bit). There are no official limits (that I could find), but 1.4GB is a common number tossed around. Felix Gerschau tested the limits of different Node versions for his blog post and came up with this data on a 64-bit architecture:

Node Version Limit
15.0.1 4.03 GB
14.15.0 4.03 GB
13.14.0 2.01 GB
12.19.0 2.01 GB
11.15.0 1.34 GB
10.15.3 1.34 GB
9.11.2 1.35 GB

So two most common ways to encounter this error is on building the application if we simply load too much data at once and run out of allocated memory. The second is through memory leaks. Even if our application can normally fit into the allocated memory size, it can over time, with the presence of a bug that is causing a memory leak, stop functioning.

The V8 garbage collector handles memory allocation for us, but it can be tricked. There is also an interesting discussion on just what is the role of this garbage collector in connection to the memory limits. Ashley Davis in his blog, proposes a theory that the reason for 1.4GB limitation is historical in nature since V8 was built on a 32-bit browser, but it might come down simply to how the garbage collector is implemented.

But the fastest and most simple solution is to simply tell the machine, how much memory to allocate.

—-max-old-space-size=X

X in this case would be the number of MB that we want to allocate. If the problem occurs when you are building your application, you could add this command into your build command that is then used in build.sh.

"build": "NODE_OPTIONS=\"--max_old_space_size=4096\" next build",

Ok now we know the main reason why this error happens, and a quick fix, that might help, but there are many more questions to delve into. First, I don’t actually understand the error message. What is a heap?

Heap is one of three integral parts of the memory, consumed by a Node.js application, next to code and stack. Code is self-explanatory, the stack is the part where the function call stack is stored, and the heap is where dynamic allocations are stored. These are all variables, strings, objects, etc. that we use in our application.

Heap is then further divided into new space and old space. (also called younger and older generation)

New space is where new allocations happen. They are usually small and don’t exceed a few megabytes in size. This is a very dynamic space, where allocations happen often and frequently. Garbage collection is also very active here.

Old space, on the other hand, consists of allocations that came from the new space, and they survived any garbage collection. Here, objects are condemned less frequently, saving CPU time.

If we now take a look at the command above, we have some more context on what it does. We reference this old_space_size there.

In the previous paragraph, I mentioned that an object can be condamned. That means that it is a candidate to be recycled within a collection cycle. Maybe I’ll take a look at what that means at some later time. Now I just want to express my amusement at all the dramatic terminology that IT uses.

Withing the same definition I also noticed the term generational hypothesis, or perhaps more commonly known(?) as infant mortality. Infant mortality. Even the definition sounds dramatic:

Infant mortality or the generational hypothesis is the observation that, in most cases, young objects are much more likely to die than old objects. Strictly, the hypothesis is that the probability of death as a function of age falls faster than exponential decay (inverse hyper-exponential), but this strict condition is not always required for techniques such as generational garbage collection to be useful.

Philosophical.

How could anyone be surprised at any of the questionable and borderline criminal google searches we do? “How to re-attach a detached head”, “kill child and fork parent”, “kill child without killing grandchildren”, etc.

Ok, maybe we just really don’t like children?

Sources: