Understanding JavaScript Memory Management: Best Practices and Solutions

Stephany Doris
Level Up Coding
Published in
7 min readMar 31, 2023

--

Google chrome: out of memory error code

Fact: Memory is a limited resource. With this is mind, it’s important to understand how much memory our application or program uses and how to manage that memory to ensure we stay performant and efficient.

As opposed to low-level languages, such as C, that have manual memory management, memory in JavaScript is mainly handled by the JavaScript engine. It automatically allocates memory when we create objects, strings, and other data types, and frees it up when it’s no longer in use.

This article, takes a deeper look at what happens under the hood, giving real code examples that will better help you to identify patterns in memory management and keep up with best practices.

Let’s get to it!

Why we should care about memory

  • Memory is a finite resource. As people pay for machines with more memory, they expect a better experience and that means using memory efficiently.
  • The other side of the performance coin: Programs are considered efficient by how fast they run and how much memory we use.
  • Performance monitoring and memory analysis. One tool that chrome devtools provides is the memory panel, where you can investigate any memory issues in your application.
  • Build better web experience. When working with memory intensive processes such as Image processing and web animations, its important to know how to fix memory issues such as memory leaks which are quite frequently.

Memory Life Cycle

The memory life cycle is the same in all programming languages:

  • We first allocate memory either manually or by creating a variable.
  • We then use the allocated memory(read/write)
  • Release the memory once it’s no longer in use

Stack memory

The stack memory is an ordered insertion place which uses the stack data structure, LIFO (Last-In-First-Out), principle. When functions are added to the stack, the last function to get passed to the stack, gets executed first.

The stack memory stores static data i.e data size is known at compile time. This includes primitive types and references. The limits of stack memory vary depending on the browser. Some important things to note:

  • Primitive types are stored directly on stack. To keep track of the current memory place, there is a special processor register called Stack Pointer. These are pointers to objects/functions located in heap memory.
  • All local variables including arguments and return value of functions are stored within the function frame block on the stack. When you exit a function, everything associated with that function is cleared from the stack.
  • Developers don’t have control over the stack memory, it is managed by the JavaScript engine.
Diagram representation of stack

Stack overflow

Stack overflow occurs when the stack exceeds its maximum size. This can happen when there’s an infinite loop or recursive functions that don’t return.

Heap memory

In contrast to stack memory, heap memory is not ordered, you allocate memory wherever you can. It’s mainly used to store objects, and the memory is dynamically allocated.

Dynamic memory allocation refers to memory that’s allocated as needed, i.e, the JS engine doesn’t allocate a fixed amount of memory. This is performed at run time as the size of memory to be allocated is unknown during compile time.

// example of dynamic memory allocation

let arr = []; // empty array

arr = Array(20).fill(1); // allocates more memory to arr, to hold 20 integers

An object can hold memory in two ways:

  • Directly by the object itself.
  • Implicitly by holding references to other objects, and therefore preventing those objects from being automatically disposed by a garbage collector.
const person = {}; // the objects holds the memory

const newPerson = person; // holds reference to person object

Some of the issues that arise with heap memory are that it gets fragmented over time. There might be enough free space but in small chunks. A good example is if we need 2gb memory for a single object, but we have 2gb in 200mb chunks in the heap. Most modern browsers do have algorithms in place to better handle this.

Stack memory & stack pointers to heap memory

Garbage collection

Garbage collection refers to the process of automatically freeing up memory when it’s no longer in use. It uses, garbage collectors, which is software used to track memory allocation and use in order to find when a piece of allocated memory is not needed any longer in which case, it will free up the memory occupied by that object.

Code Examples

/* --- allocates memory for a string --- */
let name = "Pam";

/*
Primitive values are immutable, which means that instead of changing the
original value, JavaScript creates a new one.

The line below, allocates memory for a new string
*/
name = "Jim";



/* --- Memory allocation on heap --- */
/* -- Objects located in heap will have a stack pointer that references them -- */

/* -- allocate memory in heap for our function(object) -- */
const logName = () => console.log(name);

/* -- allocate memory in heap for our object -- */
const Person = {
name: "Oscar",
age: 101
}

/* -- allocate memory in heap for our array(object) -- */
const colleagues = ["Kelly", "Ryan"];

/* allocate more memory for colleagues array */
colleagues.push("Michael");



/* --- garbage collection & reference --- */

const logName = () => {
// variable created in function frame block on stack memory
const name= "Dwight";
console.log(name);
}
/* -- Once logName function is executed and popped off the stack, name is garbage collected as it's no longer referenced -- */


/* -- Variable created on global scope/window object. Will not be garbage collected -- */
tv_show = "The Office";
window.tv_show; // returns "The Office"

// to free this memory
window.tv_show = null;

Objects are always accessed by reference. For that reason, even if an object has the exact same properties, they are not considered equal as they point to different objects in heap memory.

Memory Leaks

Memory leaks are pieces of memory that the application has used in the past and is not needed any longer but has not yet been returned back to the pool of free memory. Thus causing it to be inaccessible to new objects and often inaccessible for garbage collection. This can also lead to an error if your browser runs out of memory.

Some common causes of memory leaks include:

  • Global variables. Global variables are attached to the window object and exist for the duration of the program’s execution. Since the global context has a reference to itself, they’re always kept in memory and therefore not collected.
  • Forgotten timers and callbacks. When you set up an event listener or setInterval function to execute every x seconds, it has the potential to make the memory usage of the application go up.

Level Up Coding

Thanks for being a part of our community! Before you go:

🚀👉 Join the Level Up talent collective and find an amazing job

--

--

Writing about The Web, Performance and Standards | Software engineer