Inspect Node.js Memory Programmatically with V8
Monitoring memory usage is crucial for maintaining stable and
performant Node.js applications. This article provides a straightforward
guide on how to use the built-in v8 module in Node.js to
programmatically inspect memory allocation. You will learn how to
retrieve general heap statistics, analyze specific heap space
distributions, and generate heap snapshots for deep-dive debugging
without relying on external APM tools.
Accessing the V8 Module
Node.js provides the v8 module out of the box, meaning
you do not need to install any external dependencies. To start
inspecting your application’s memory, import the module into your
script:
const v8 = require('v8');Retrieving Heap Statistics
The most common way to inspect memory allocation is by using
v8.getHeapStatistics(). This method returns an object
containing metrics about the V8 heap helper, such as the total heap
size, the used heap size, and the physical limit the heap can grow
to.
const heapStats = v8.getHeapStatistics();
console.log(`Total Heap Size: ${(heapStats.total_heap_size / 1024 / 1024).toFixed(2)} MB`);
console.log(`Used Heap Size: ${(heapStats.used_heap_size / 1024 / 1024).toFixed(2)} MB`);
console.log(`Heap Size Limit: ${(heapStats.heap_size_limit / 1024 / 1024).toFixed(2)} MB`);Key Properties Explained:
total_heap_size: The total amount of memory currently committed for the V8 heap.used_heap_size: The amount of memory actually utilized by your application’s objects. A continuously rising number here may indicate a memory leak.heap_size_limit: The maximum size the heap can reach before the Node.js process crashes with an out-of-memory error.
Analyzing Heap Space Statistics
To inspect how memory is distributed across different V8 generation
areas, use v8.getHeapSpaceStatistics(). V8 divides memory
into different spaces (like the new space for short-lived objects, and
the old space for long-lived objects) to optimize garbage
collection.
const heapSpaces = v8.getHeapSpaceStatistics();
heapSpaces.forEach(space => {
console.log(`Space: ${space.space_name}`);
console.log(` Size: ${(space.space_size / 1024 / 1024).toFixed(2)} MB`);
console.log(` Used: ${(space.space_used_size / 1024 / 1024).toFixed(2)} MB`);
console.log(` Available: ${(space.space_available_size / 1024 / 1024).toFixed(2)} MB`);
});This breakdown is particularly useful for identifying whether memory
pressure is building up in the old_space (indicative of
long-term leaks) or the new_space.
Generating Heap Snapshots Programmatically
When you detect abnormal memory growth through statistics, you can programmatically generate a heap snapshot. A heap snapshot records all active JS objects and allocation paths, which can then be loaded into Chrome DevTools for visualization.
Use v8.writeHeapSnapshot() to save the snapshot to a
file:
const fs = require('fs');
const path = require('path');
function captureMemorySnapshot() {
const filename = path.join(__dirname, `snapshot-${Date.now()}.heapsnapshot`);
const filepath = v8.writeHeapSnapshot(filename);
console.log(`Heap snapshot successfully written to: ${filepath}`);
}
// Example usage: Trigger snapshot when used heap exceeds 80% of limit
const stats = v8.getHeapStatistics();
if (stats.used_heap_size > stats.heap_size_limit * 0.8) {
captureMemorySnapshot();
}Once the .heapsnapshot file is generated, open Google
Chrome, navigate to DevTools > Memory, right-click
the Profiles sidebar, select Load, and
upload your file to inspect the object allocation tree.