memlab
memlab is an E2E testing and analysis framework for finding JavaScript memory
leaks in Chromium. The CLI Toolbox and library provide extensible interfaces
for analyzing heap snapshots taken from Chrome/Chromium, Node.js, Hermes, and Electron.js.
CLI Usage
Install the CLI
npm install -g @memlab
Find Memory Leaks
To find memory leaks in Google Maps, you can create a scenario file defining how
to interact with the Google Maps, let's name it test-google-maps.js
:
function url() {
return 'https://www.google.com/maps/@37.386427,-122.0428214,11z';
}
async function action(page) {
await page.click('button[aria-label="Hotels"]');
}
async function back(page) {
await page.click('[aria-label="Clear search"]');
}
module.exports = {action, back, url};
Now run memlab with the scenario file, memlab will interact with
the web page and detect memory leaks with built-in leak detectors:
memlab run --scenario test-google-maps.js
If you want to use a self-defined leak detector, add a filterLeak
callback
in the scenario file. filterLeak
will be called for every unreleased heap
object (node
) allocated by the target interaction.
function filterLeak(node, heap) {
// ... your leak detector logic
// return true to mark the node as a memory leak
};
heap
is the graph representation of the final JavaScript heap snapshot.
Heap Analysis and Investigation
View which object keeps growing in size during interaction in the previous run:
memlab analyze unbound-object
Analyze pre-fetched v8/hermes .heapsnapshot
files:
memlab analyze unbound-object --snapshot-dir <DIR_OF_SNAPSHOT_FILES>
Use memlab analyze
to view all built-in memory analyses. For extension, view the doc site.
View retainer trace of a particular object:
memlab trace --node-id <HEAP_OBJECT_ID>
Use memlab help
to view all CLI commands.
APIs
Use the memlab
npm package to start a E2E run in browser and detect memory leaks.
const memlab = require('memlab');
const scenario = {
url: () => 'https://www.google.com/maps/@37.386427,-122.0428214,11z',
action: async (page) => await page.click('button[aria-label="Hotels"]'),
back: async (page) => await page.click('[aria-label="Clear search"]'),
}
memlab.run({scenario});