facebook / memlab

A framework for finding JavaScript memory leaks and analyzing heap snapshots
https://facebook.github.io/memlab/
MIT License
4.36k stars 119 forks source link

feat: support capturing and analyzing node.js heap #4

Closed JacksonGL closed 2 years ago

JacksonGL commented 2 years ago

Enables memlab to capture and return the current node.js heap, this could be useful in the following ways:

For example:

import {getCurrentNodeHeap} from '@memlab/core';

// code logic that may leak Class
maybeLeaky();

// expect there is no strong references pointing to any objects constructed by Class
const heap = await getCurrentNodeHeap();
expect(heap.hasObjectWithClassName('Class')).toBe(false);
function f1(o) {
  ... 
  // rabbitHole may add other refereces to o, which keeps it from being GCed
  rabbitHole(o);
  ...
}

let o = new InstantObject();
o.__memlab_tag = 'maybe-leak-from-f1'
f1(o);
// we hope to release o
o = null;

// expect no other strong references to o are added by f1 and the rabbitHole
const heap = await getCurrentNodeHeap();
expect(heap.hasObjectWithTag('maybe-leak-from-f1')).toBe(false);
mrsharpoblunto commented 2 years ago

I wonder if a slightly nicer/stricter API would be

import {tagObject, getCurrentNodeHeap} from '@memlab/core';
let o = new InstantObject();
tagObject(o, 'maybe-leak-from-f1');

Also, not sure if it would make the internals more complicated, but instead of __memlab_tag - would it be possible to use a Symbol instead of a string key to guarentee that props added by memlab wont change application logic (i.e. it wouldn't show up in prop enumerations or in serialized JSON output etc.)

JacksonGL commented 2 years ago

I wonder if a slightly nicer/stricter API would be

import {tagObject, getCurrentNodeHeap} from '@memlab/core';
let o = new InstantObject();
tagObject(o, 'maybe-leak-from-f1');

Also, not sure if it would make the internals more complicated, but instead of __memlab_tag - would it be possible to use a Symbol instead of a string key to guarentee that props added by memlab wont change application logic (i.e. it wouldn't show up in prop enumerations or in serialized JSON output etc.)

Update the commit by adding a new tabObject API that doesn't modify the tagged object. The idea is using a WeakSet to store references to tagged objects, and heap.hasObjectWithTag will traverse the WeakSet and check that the object with associated tag has no strong references in heap.

facebook-github-bot commented 2 years ago

@JacksonGL has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.