While JavaScript runtimes use garbage collection to manage memory, this does not rule out the possibility of leaking memory. To detect all possible cases where memory is leaked, Facebook created and open-sourced MemLab, a tool able to run predefined, automatable test scenarios and analyze heapshot diffs.
In a nutshell, MemLab finds memory leaks by running a headless browser through predefined test scenarios and diffing and analyzing the JavaScript heap snapshots.
Based on the diff results, MemLab builds a list of potential memory leaks and for each of them generates a retainer traces, i.e. an object reference chain from the garbage collector roots. By inspecting the retainer traces, you can visualize which references should have been set to null
for proper collection. Additionally, to reduce the amount of information that needs to be analyzed, MemLab is able to cluster leaked objects based on the similarity of their retainer traces and show them for each cluster instead of for each potential leak.
There are a number of cases where JavaScript may leak memory. For example, say Facebook engineers Liang Gong and Glenn Conner, when you log
an object to Chrome console, Chrome will take a hidden reference to it that will prevent it from being collected. Other cases where you can have leaks or unbound memory growth are related to the accidental use of global variables, to forgotten timers or callbacks, and to out-of-DOM references, says auth0 engineer Sebastian Peyrott.
While Chrome Developer Tools provides the essential means to inspect memory behaviour of JavaScript code, including the timeline view and the profiles view, this is not straightforward and cannot be automated. Instead, MemLab can be easily integrated in a CI/CD pipeline, say Gong and Conner.
For in-browser memory leak detection, the only input MemLab requires from developers is a test scenario file that defines how to interact with the webpage by overriding three callbacks with the Puppeteer API and CSS selectors. MemLab automatically diffs the JavaScript heap, refines memory leaks, and aggregates results.
MemLab is also able to generate a graph-view of the JavaScript head, where each heap object is represented as a node, while references are represented through edges. Besides providing general information such as the total retained size of a given set of components, the graph can also be accessed programmatically for self-memory checking. Developers can also use a CLI and an API to explore possibilities of memory optimization of their apps.
Facebook has been using MemLab for a few years, which allowed them to reduce OOM crashes on Facebook.com by 50 percent in the first half of 2021. They also used the heap graph view and the heap analysis API to further improve memory behaviour of React Fibers and to improve Relay memory interning.
MemLab is open source and can be installed running npm i -g memlab
.