N|Solid Documentation

Versions

Heap Snapshots

If you have a memory leak or performance issue, taking heap snapshots is a great way to help identify the underlying problem. N|Solid provides you with two ways to do this, a command-line friendly method and via our console.

Analyzing Heap Snapshots

Heap Snapshots capture a record of all live JavaScript objects available in your Node application, at the time the snapshot is captured. The objects are grouped by their constructor name, with aggregated counts of the total number of objects, their shallow size, and their retained size as columns in the Constructors view.

Shallow Size indicates the amount of space the object uses for its own properties. For instance, an object with no properties will have a very small shallow size, where an object with a number of properties will have a larger shallow size.

Retained Size indicates the amount of space the object is referencing, and keeping from being garbage collected.

From the Constructors view of the snapshot, you can sort by constructor name, number of objects, shallow size and retained size. You can also filter the list by constructor name.

You can use the number of objects value to look for the objects that are leaking, and you can use the retained size value to look for objects referencing those leaking objects.

In cases where you are leaking objects - and thus consuming more memory than you should be - sorting by number of objects and by retained size can provide a good indication of where to look for the cause of the leak. A large number of objects of a particular type may be an indication that these objects are still being referenced by other objects, when they could be garbage collected. A large retained size may be an indication that these objects are referencing more objects than they should be, keeping them from being garbage collected.

Taking Heap Snapshots with the N|Solid Console

Using N|Solid's Console, developers to take a series of snapshots and quickly switch between them to better identify problematic areas.

  1. Launch the console and select the application of interest "All applications"
  2. Select the process of interest "Select process"
  3. Expand out the details panel and select ‘+ New Snapshot’
    "New snapshot" This will take the snapshot and open the results in the snapshot window. To retake the snapshot, click the 'New Snapshot' button. The 'Related Snapshots' section in the previous screen provides a record of all the snapshots in the session. "Retake snapshot"
  4. Once the snapshot completes you can navigate through the various objects indexed during the snapshot process. As there can be a large number of indexed objects, you can use the Filter search box to narrow the results. Below you can see a listing of the various Array objects found in memory. To take another snapshot, simply press the New Snapshot button to the left. "Filter" Snapshots taken in the N|Solid Console can 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 the Download Snapshot button "Download snapshot"

Taking 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.

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'd like to track, as opposed to using literal objects. When using literal objects for trackable objects, those objects will be aggregated under the Object constructor name, along with all the other literal objects your program uses.

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 these objects in a snapshot, use 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.

If you'd like a bit 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]
  }
}

Snapshots Using the N|Solid Node API

If you want to create a Heap Snapshot progamatically from within your application and have the resulting snapshot saved to your N|Solid console, you can do this using the N|Solid Node API.

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