JavaScript's Memory Management Explained
-
Even though the JavaScript engine manages memory for us, it’s good to know what happens under the hood
Most of the time, you can probably get by fine not knowing anything about memory management as a JavaScript developer. Afterall, the JavaScript engine handles this for you.
At one point or another, though, you’ll encounter problems, like memory leaks, that you can only solve if you know how memory allocation works.
In this article, I’ll introduce you to how memory allocation and garbage collection works and how you can avoid some common memory leaks
Memory life cycle
In JavaScript, when we create variables, functions, or anything you can think of, the JS engine allocates memory for this and releases it once it’s not needed anymore.
Allocating memory is the process of reserving space in memory, while releasing memory frees up space, ready to be used for another purpose.
Every time we assign a variable or create a function, the memory for that always goes through the same following stages:
Allocate memory
JavaScript takes care of this for us: It allocates the memory that we will need for the object we created.
Use memory
Using memory is something we do explicitly in our code: Reading and writing to memory is nothing else than reading or writing from or to a variable.
Release memory
This step is handled as well by the JavaScript engine. Once the allocated memory is released, it can be used for a new purpose
The memory heap and stack
We now know that for everything we define in JavaScript, the engine allocates memory and frees it up once we don’t need it anymore.
The next question that came to my mind was: Where is this going to be stored?
JavaScript engines have two places where they can store data: The memory heap and stack.
Heaps and stacks are two data structures that the engine uses for different purposes.
A stack is a data structure that JavaScript uses to store static data. Static data is data where the engine knows the size at compile time. In JavaScript, this includes primitive values (strings, numbers, booleans, undefined, and null) and references, which point to objects and functions.
Since the engine knows that the size won’t change, it will allocate a fixed amount of memory for each value.
The process of allocating memory right before execution is known as static memory allocation.
Because the engine allocates a fixed amount of memory for these values, there is a limit to how large primitive values can be.
The limits of these values and the entire stack vary depending on the browser.
Heap: Dynamic memory allocation
The heap is a different space for storing data where JavaScript stores objects and functions.
Unlike the stack, the engine doesn’t allocate a fixed amount of memory for these objects. Instead, more space will be allocated as needed.
Allocating memory this way is also called dynamic memory allocation.
To get an overview, here are the features of the two storages compared side by side
Examples
const person = { name: 'John', age: 24, };
JS allocates memory for this object in the heap. The actual values are still primitive, which is why they are stored in the stack.
const hobbies = ['hiking', 'reading'];
Arrays are objects as well, which is why they are stored in the heap.
let name = 'John'; // allocates memory for a string const age = 24; // allocates memory for a number name = 'John Doe'; // allocates memory for a new string const firstName = name.slice(0,4); // allocates memory for a new string
Primitive values are immutable, which means that instead of changing the original value, JavaScript creates a new one
References in JavaScript
All variables first point to the stack. In case it’s a non-primitive value, the stack contains a reference to the object in the heap.
The memory of the heap is not ordered in any particular way, which is why we need to keep a reference to it in the stack. You can think of references as addresses and the objects in the heap as houses that these addresses belong to
Note: Remember that JavaScript stores objects and functions in the heap. Primitive values and references are stored in the stack.
In this picture, we can observe how different values are stored. Note how person and newPerson both point to the same object.
Ref: Memory Management - MDN Web Docs
Ref: https://felixgerschau.com/javascript-memory-management/