Skip to main content
Version: 5.0.0

Heap Snapshots

When faced with a memory leak or performance issue, taking heap snapshots is a great way to help identify the underlying problem. N|Solid provides several ways to capture snapshots: the N|Solid Console, the N|Solid CLI, and the N|Solid Node API.

Taking Heap Snapshots with the N|Solid Console

Using the N|Solid Console, take a series of snapshots and quickly switch between them to better identify problematic areas:

  1. Launch the console and locate the Processes list on the right. "All applications"
  2. Click the process ID of the process of interest, and click New Heap Snapshot from the Process Detail view. "New snapshot"
  3. Select the thread ID of the process of interest, and click Get Heap Snapshot button. "New snapshot"
  4. Once the snapshot completes, a green alert will pop up on the page. Go to the Assets tab to find the heap snapshot.
  5. Snapshots taken in the N|Solid Console need be downloaded to your local drive for exploration via a 3rd party tool (i.e. Chrome Developer Tools). If you wish to download the snapshot for analysis through other tools, simply click Download on the right.
  6. If you want a particular snapshot to be saved and prevented from being deleted automatically, click Save to mark it for retention.

Note: You can trigger heap snapshots automatically by creating a customized saved view on a memory-related metric (such as Heap Used > 128MB) that triggers a heap snapshot action when when processes exceed the metric threshold. This is particularly useful for generating heap snapshots on applications that have rare or intermittent memory leaks.

Taking Heap Snapshots from the Command Line Interface (CLI)

N|Solid's Command Line Interface (CLI) is a great way to quickly take heap snapshots from remote processes for local examination. You can learn more about the snapshot command in the N|Solid Command Line Interface (CLI) reference.

Heap Snapshots Using the N|Solid Node API

Use the N|Solid Node API to programmatically create a heap snapshot from within your application. The resulting snapshot(s) can be saved to your N|Solid Console. Heap Snapshots can be taken asynchronously and synchronously.

The following code snippet takes a heap snapshot asynchronously:

const nsolid = require('nsolid')
nsolid.snapshot(err => {
if (err) {
// The snapshot could not be created!
}
})

The following code snippet takes a heap snapshot synchronously:

const nsolid = require('nsolid')
try {
nsolid.snapshot()
} catch (err) {
// The snapshot could not be created!
}

Best Practices

Using constructors will show class names in heap snapshots. Since the heap snapshot groups objects by constructor name, if at all possible you should use named constructors for objects you would like to track, as opposed to using literal objects. Literal objects will be aggregated under the Object constructor name.

For instance, the following code snippet creates objects which will be categorized under the Object constructor:

trackableObject = {x: "some value", y: "another value"}

To be able to track trackableObject in a snapshot, make it an instance of a specifically named class:

trackableObject = new TrackableObject()
trackableObject.x = "some value"
trackableObject.y = "another value"
// ...
function TrackableObject() {}

You'll then see these objects grouped by themselves in the heap snapshot.

For more of an "inline" feel, you can enhance your constructor to take initialization values:

trackableObject = new TrackableObject({x: "some value", y: "another value"})
// ...
function TrackableObject(initialValue) {
this.x = initialValue.x
this.y = initialValue.y

With EcmaScript 6 parameter destructuring, you can make it a little shorter:

trackableObject = new TrackableObject({x: "some value", y: "another value"})
// ...
function TrackableObject({x, y}) {
this.x = x
this.y = y
}

You can also make the constructor open-ended regarding the properties:

trackableObject = new TrackableObject({x: "some value", y: "another value"})
// ...
function TrackableObject(initialValue) {
for (var key in initialValue) {
this[key] = initialValue[key]
}
}