tezvyn:

Heap Snapshots: Finding Node.js Memory Leaks

AI-drafted, machine-checkedSource: nodejs.orgintermediate

A heap snapshot is a photograph of your app's memory. Use it to diagnose leaks by comparing snapshots over time to see which objects grow. The big footgun: taking one freezes your app and can double memory usage, risking a crash in production.

WHY IT EXISTS: Node.js is garbage-collected, but memory leaks still happen when old, unneeded objects are unintentionally kept alive by references. When memory usage grows indefinitely without returning to a baseline, you need a way to inspect the heap to find out what is being retained and why.

THE MENTAL MODEL: Think of a heap snapshot as a detailed census of your application's memory at a single moment. It lists every object (the 'residents') and shows the chain of references (the 'relationships') keeping each one alive. By comparing two censuses taken at different times, you can spot which populations are growing out of control, pointing you to a memory leak.

HOW IT WORKS: The V8 engine generates a file representing the entire heap graph. You load this snapshot file into a tool like Chrome Developer Tools. The DevTools UI lets you inspect objects, see their retained size (memory freed if the object were deleted), and view the 'retainer path'—the chain of references preventing an object from being garbage collected. To find a leak, you compare two snapshots to see which object counts have increased.

WHEN TO USE IT: Use heap snapshots when you observe steadily increasing memory usage that doesn't go down after garbage collection. The typical workflow is to take one snapshot, perform actions you suspect are causing the leak, and then take a second snapshot to compare against the first. This is the definitive tool for post-mortem analysis of a memory leak.

WHEN NOT TO USE IT: Do not use heap snapshots for real-time monitoring. The process is extremely heavyweight. Taking a snapshot blocks the main event loop thread, sometimes for over a minute, making your application unresponsive. It also temporarily consumes significant memory to build the snapshot itself, which can cause the process to exceed its memory limit and crash. In production, only take snapshots on instances that can be safely terminated.

ONE CANONICAL EXAMPLE: A common leak source is an event emitter where listeners are added but never removed. To debug this, you'd start your app, take a heap snapshot, then simulate activity that registers listeners. After some time, take a second snapshot. In Chrome DevTools, comparing the two would reveal a large number of listener objects retained by the event emitter, showing you exactly where the leak is.

Read the original → nodejs.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.