Heap Dump Analysis
There are a number of reason why one would want to do a heap dump but in particular, they are helpful for find memory intensive operations and leaks. There are two major types of heap dumps that are available to node developers. The first is a JavaScript heap dump, and the second is a native heap dump. The JS heap dump is much more common and is the default heap dump that is generated by node. It is useful when analyzing JS generated objects that are managed by the runtime. However there is one major limitation to the JS heap dump, and that is that it does not include native objects. This is where the native heap dump comes in handy. The native heap dump is a snapshot of the entire process memory, and includes objects that are allocated by C/C++ code, including native modules in use by the application. The limitation to the native heap dump is that it will not include any JS objects that are allocated by the V8 runtime. Those are generally created within mmap'ed pages and the native heap dump tools are specific to C objects that are created with malloc and destroyed via free. C++ is also covered as new and delete are wrappers around malloc and free. This is why it is important to understand how to analyze both types of memory usage.
JavaScript Heap Dumpโ
Node has built in V8 heap dump access and its a very powerful tool for analyzing memory usage. Understanding how the dump is created will both help to understand how it is displayed and how to use the analysis more effectively.
The V8 heap dump is a stop the world process because walking the entire heap graph is necessary to create one. This is similar to a full, major garbage collection event. The VM starts at the heap entrance node and walks the entire graph and makes note of every edge that connects each node along the way. Nodes are JSObjects and edges are references between those objects.
By time the whole heap is walked the full size and values of all nodes are known and all of the connections between those nodes is well understood. The object that is returned is a set of three arrays, the nodes, the edges and the string values that are encountered (because strings are themselves arrays of characters in C so they are treated a bit differently by V8).
Creating a V8 heap dumpโ
There are two functions for creating a heap dump but both call the same functionality under the hood. One streams the result, require("v8").getHeapSnapshot([options]), and is primarily intended for use by the Chrome devtools button to "take a snapshot". The second writes the heap dump to a file, require("v8").writeHeapSnapshot(filename[,options]).
The optional options argument, in both cases, is the same and contains two props.exposeInternals and exposeNumericValues to enrich the dump. In many cases its the application layer that one wants to debug so exposeInternals is not usually necessary. In V8 numbers are stored as 32bit integers and the size of pointers is also 32bits. So as an optimization, the pointer to the numeric value can be eliminated and the value itself can be stored in the Address of the Value instead. exposeNumericValues transcribes those "pointers" to the actual numeric value and appends them to the dump.
Because heap analysis happens frequently during Lodestar development there is a helper api endpoint to capture a heap dump. It is IMPORTANT that this endpoint is not public facing as it will open the threat of DDOS attack.
The endpoint accepts a POST request and you may include an optional dirpath query parameter to specify the directory where the heap dump will be written. If the dirpath is not specified then the heap dump will be written to the current working directory.
To create a Lodestar heap dump you can use the following command:
curl -X POST http://localhost:9596/eth/v1/lodestar/write_heapdump?dirpath=/some/directory/path
Viewing a V8 heap dumpโ
It is best to analyze on a local development machine so if Lodestar is running on a cloud instance download the dump to the local environment. Open Chrome, or any Chromium based browser (the example photos were taken using Brave). In the url bar type chrome:://inspect to bring up the DevTools menu (in brave the url will be rewritten to brave://inspect).

Click on the Open dedicated DevTools for Node link to open the node specific window and click on the Memory tab as shown below.

Load the profile by either right-clicking on the left pane or by clicking the Load button at the bottom.
