Skip to main content

Memory Management in JavaScript

How Memory Works​

JavaScript automatically allocates memory when values are created and frees it when they are no longer used. This process is called Garbage Collection.

Memory Lifecycle​

  1. Allocate — Memory is allocated when you declare variables, objects, or functions.
  2. Use — Read/write operations on the allocated memory.
  3. Release — Memory is freed when it's no longer needed.

Stack vs Heap​

FeatureStackHeap
StoresPrimitives & referencesObjects & functions
SizeFixed, smallDynamic, large
AccessFast (LIFO)Slower (random access)
ManagementAutomatic (scope-based)Garbage collected
script.js
// Stack: primitive value stored directly
let name = "Ajay"; // stored on stack

// Heap: object stored on heap, reference on stack
let user = { name: "Ajay" }; // reference on stack → object on heap

Garbage Collection​

JavaScript uses automatic garbage collection. The main algorithm is Mark-and-Sweep:

  1. The GC starts from root objects (global object, local variables in current scope).
  2. It marks all objects reachable from roots.
  3. It sweeps (frees) all unmarked (unreachable) objects.

Reference Counting (older approach)​

Counts how many references point to an object. When count reaches 0, object is freed. Problem: fails with circular references.

script.js
// Circular reference — wouldn't be freed by reference counting
function createCycle() {
let a = {};
let b = {};
a.ref = b;
b.ref = a;
// After function returns, mark-and-sweep CAN collect these
// Reference counting would NOT collect them
}

Common Memory Leaks​

1. Accidental Globals​

script.js
function leak() {
name = "oops"; // no let/const/var — creates global variable
}

2. Forgotten Timers​

script.js
const timer = setInterval(() => {
// holds reference to outer scope
console.log("running...");
}, 1000);

// Fix: clearInterval(timer) when done

3. Detached DOM References​

script.js
let button = document.getElementById("btn");
document.body.removeChild(button);
// 'button' variable still holds a reference — memory not freed
button = null; // Fix: remove the reference

4. Closures Holding Large Data​

script.js
function outer() {
let bigData = new Array(1000000).fill("x");
return function inner() {
// inner() keeps bigData alive even if it doesn't use it
console.log("hello");
};
}

WeakRef & WeakMap​

Use WeakMap and WeakSet to hold references that don't prevent garbage collection:

script.js
let obj = { data: "important" };
let weakMap = new WeakMap();
weakMap.set(obj, "metadata");

obj = null; // object can now be garbage collected
// weakMap entry is automatically removed

Key Takeaways​

  • Primitives go on the stack, objects on the heap.
  • JavaScript uses mark-and-sweep garbage collection.
  • Memory leaks happen when references to unused data are accidentally kept alive.
  • Use WeakMap/WeakSet for references that shouldn't prevent GC.