A Gentle Intro to Garbage Collection
Imagine a project-management SPA where users switch between boards, tasks, and chats for hours. Autosave timers tick away, caches hold user data, event listeners buzz, and drag-and-drop cards mount and unmount nonstop. If those timers, caches, and listeners aren’t cleaned up, memory leaks pile up, and your app drags.
What Is Garbage Collection?
Think of your app’s memory as a closet. Every time you create a variable or an object, you’re adding something to that closet. Eventually, stuff you don’t need anymore piles up. Someone has to clean it out. This is the garbage collector (GC).
In JavaScript, the GC automatically frees memory occupied by objects no longer reachable by your code. If your program can’t access something anymore, GC will discard it.
Reachability: The GC’s Only Rule
GC only checks if it can still reach an object. Reachable objects stay in memory; unreachable ones become garbage.
Example of reachability:
function createUser() {
let user = { name: 'Alice' };
return user;
}
const alice = createUser(); // `alice` holds the object, so it’s reachable.
Example of garbage collection:
let temp = { data: 'Transient info' };
// `temp` holds the object in memory
temp = null; // Removes the only reference
// The object becomes unreachable and eligible for garbage collection
How Mark-and-Sweep Works
Most JavaScript engines—including V8—use a variant of the mark-and-sweep algorithm:
- Mark Phase
The GC starts from the roots (global objects, call stack, closures) and “marks” every object it can reach. - Sweep Phase
The GC scans the entire heap and frees any object that wasn’t marked as reachable.
This two-step process ensures that only objects still in use stay in memory. Once the sweep completes, all marks reset, ready for the next cycle.
Common Ways Memory Leaks Sneak In
Even with GC, leaks happen when your code accidentally keeps references alive. Frequent culprits:
- Timers left running after UI changes
- Event listeners not removed when elements go away
- Detached DOM nodes still held by variables
- Caches (Maps/arrays) that grow forever
- Closures capturing variables longer than needed
Why You Should Care
Small leaks might seem minor early on. After hours of use, they accumulate; your app slows, crashes, or drains battery.
Understanding reachability and GC basics helps you write cleaner, faster, more reliable code.
What’s Next
I’ve split this topic into separate posts. Up next: how WeakMap
and
WeakSet
let you store data tied to objects
without preventing GC from doing its job.