Skip to main content

Package: @memlab/heap-analysis

Classes

Type Aliases

AnalyzeSnapshotResult: Object

This is the return type from calling analyzeSnapshotFromFile or analyzeSnapshotsInDirectory.

NameTypeDescription
analysisOutputFilestringfile path of the console output of the heap analysis call

HeapAnalysisOptions: Object

This is the auto-generated arguments passed to all the process method that your self-defined heap analysis should implement. You are not supposed to construct instances of this class.

For code examples on how this options could be used, see getSnapshotFileForAnalysis, loadHeapSnapshot, or snapshotMapReduce.


RunHeapAnalysisOptions: Object

This is the input option for analyzeSnapshotFromFile and analyzeSnapshotsInDirectory.

NameTypeDescription
workDir?stringspecify the working directory to where the intermediate, logging, and output files should be saved

Functions

getDominatorNodes(ids, snapshot)

This API calculate the set of dominator nodes of the set of input heap objects.

  • Parameters:
    • ids: Set<number> | Set of ids of heap objects (or nodes)
    • snapshot: IHeapSnapshot | heap loaded from a heap snapshot
  • Returns: Set<number> | the set of dominator nodes/objects
    • Examples:
import {dumpNodeHeapSnapshot} from '@memlab/core';
import {getFullHeapFromFile, getDominatorNodes} from '@memlab/heap-analysis';

class TestObject {}

(async function () {
const t1 = new TestObject();
const t2 = new TestObject();

// dump the heap of this running JavaScript program
const heapFile = dumpNodeHeapSnapshot();
const heap = await getFullHeapFromFile(heapFile);

// find the heap node for TestObject
let nodes = [];
heap.nodes.forEach(node => {
if (node.name === 'TestObject' && node.type === 'object') {
nodes.push(node);
}
});

// get the dominator nodes
const dominatorIds = getDominatorNodes(
new Set(nodes.map(node => node.id)),
heap,
);
})();

getFullHeapFromFile(file)

Load and parse a .heapsnapshot file and calculate meta data like dominator nodes and retained sizes.

  • Parameters:
    • file: string | the absolute path of the .heapsnapshot file
  • Returns: Promise<IHeapSnapshot> | the heap graph representation instance that supports querying the heap
  • Examples:
import {dumpNodeHeapSnapshot} from '@memlab/core';
import {getFullHeapFromFile} from '@memlab/heap-analysis';

(async function (){
const heapFile = dumpNodeHeapSnapshot();
const heap = await getFullHeapFromFile(heapFile);
})();

getHeapFromFile(file)

deprecated


getSnapshotDirForAnalysis(options)

Get the absolute path of the directory holding all the heap snapshot files passed to the hosting heap analysis via HeapAnalysisOptions.

This API is supposed to be used within the overridden process method of an BaseAnalysis instance.

  • Parameters:
    • options: HeapAnalysisOptions | this is the auto-generated input passed to all the BaseAnalysis instances
  • Returns: Nullable<string> | the absolute path of the directory
  • Examples:
import type {IHeapSnapshot} from '@memlab/core';
import type {HeapAnalysisOptions} from '@memlab/heap-analysis';
import {getSnapshotFileForAnalysis, BaseAnalysis} from '@memlab/heap-analysis';

class ExampleAnalysis extends BaseAnalysis {
public getCommandName(): string {
return 'example-analysis';
}

public getDescription(): string {
return 'an example analysis for demo';
}

async process(options: HeapAnalysisOptions): Promise<void> {
const directory = getSnapshotDirForAnalysis(options);
}
}

Use the following code to invoke the heap analysis:

const analysis = new ExampleAnalysis();
// any .heapsnapshot file recorded by memlab or saved manually from Chrome
await analysis.analyzeSnapshotFromFile(snapshotFile);

The new heap analysis can also be used with analyze, in that case getSnapshotDirForAnalysis use the snapshot directory from BrowserInteractionResultReader.


getSnapshotFileForAnalysis(options)

Get the heap snapshot file's absolute path passed to the hosting heap analysis via HeapAnalysisOptions.

This API is supposed to be used within the overridden process method of an BaseAnalysis instance.

  • Parameters:
    • options: HeapAnalysisOptions | this is the auto-generated input passed to all the BaseAnalysis instances
  • Returns: string | the absolute path of the heap snapshot file
  • Examples:
import type {IHeapSnapshot} from '@memlab/core';
import type {HeapAnalysisOptions} from '@memlab/heap-analysis';
import {getSnapshotFileForAnalysis, BaseAnalysis} from '@memlab/heap-analysis';

class ExampleAnalysis extends BaseAnalysis {
public getCommandName(): string {
return 'example-analysis';
}

public getDescription(): string {
return 'an example analysis for demo';
}

async process(options: HeapAnalysisOptions): Promise<void> {
const file = getSnapshotFileForAnalysis(options);
}
}

Use the following code to invoke the heap analysis:

const analysis = new ExampleAnalysis();
// any .heapsnapshot file recorded by memlab or saved manually from Chrome
await analysis.analyzeSnapshotFromFile(snapshotFile);

The new heap analysis can also be used with analyze, in that case getSnapshotFileForAnalysis will use the last heap snapshot in alphanumerically ascending order from BrowserInteractionResultReader.


loadHeapSnapshot(options)

Load the heap graph based on the single JavaScript heap snapshot passed to the hosting heap analysis via HeapAnalysisOptions.

This API is supposed to be used within the process implementation of an BaseAnalysis instance.

  • Parameters:
    • options: HeapAnalysisOptions | this is the auto-generated input passed to all the BaseAnalysis instances
  • Returns: Promise<IHeapSnapshot> | the graph representation of the heap
  • Examples:
import type {IHeapSnapshot} from '@memlab/core';
import type {HeapAnalysisOptions} from '@memlab/heap-analysis';
import {loadHeapSnapshot, BaseAnalysis} from '@memlab/heap-analysis';

class ExampleAnalysis extends BaseAnalysis {
public getCommandName(): string {
return 'example-analysis';
}

public getDescription(): string {
return 'an example analysis for demo';
}

async process(options: HeapAnalysisOptions): Promise<void> {
const heap = await loadHeapSnapshot(options);
// doing heap analysis
}
}

Use the following code to invoke the heap analysis:

const analysis = new ExampleAnalysis();
// any .heapsnapshot file recorded by memlab or saved manually from Chrome
await analysis.analyzeSnapshotFromFile(snapshotFile);

The new heap analysis can also be used with analyze, in that case loadHeapSnapshot will use the last heap snapshot in alphanumerically ascending order from BrowserInteractionResultReader.


snapshotMapReduce<T1, T2>(mapCallback, reduceCallback, options)

When a heap analysis is taking multiple heap snapshots as input for memory analysis (e.g., finding which object keeps growing in size in a series of heap snapshots), this API could be used to do MapRedue on all heap snapshots.

This API is supposed to be used within the process implementation of an BaseAnalysis instance that is designed to analyze multiple heap snapshots (as an example, finding which object keeps growing overtime)

Type parameters

NameDescription
T1the type of the intermediate result from each map function call
T2the type of the final result of the reduce function call
  • Parameters:
    • mapCallback: (snapshot: IHeapSnapshot, i: number, file: string) => T1 | the map function in MapReduce, the function will be applied to each heap snapshot
    • reduceCallback: (results: T1[]) => T2 | the reduce function in MapReduce, the function will take as input all intermediate results from all map function calls
    • options: HeapAnalysisOptions | this is the auto-generated input passed to all the BaseAnalysis instances
  • Returns: Promise<T2> | the return value of your reduce function
  • Examples:
import type {IHeapSnapshot} from '@memlab/core';
import type {HeapAnalysisOptions} from '@memlab/heap-analysis';
import {snapshotMapReduce, BaseAnalysis} from '@memlab/heap-analysis';

class ExampleAnalysis extends BaseAnalysis {
public getCommandName(): string {
return 'example-analysis';
}

public getDescription(): string {
return 'an example analysis for demo';
}

async process(options: HeapAnalysisOptions): Promise<void> {
// check if the number of heap objects keeps growing overtime
const isMonotonicIncreasing = await snapshotMapReduce(
(heap) => heap.nodes.length,
(nodeCounts) =>
nodeCounts[0] < nodeCounts[nodeCounts.length - 1] &&
nodeCounts.every((count, i) => i === 0 || count >= nodeCounts[i - 1]),
options,
);
}
}

Use the following code to invoke the heap analysis:

const analysis = new ExampleAnalysis();
// snapshotDir includes a series of .heapsnapshot files recorded by
// memlab or saved manually from Chrome, those files will be loaded
// in alphanumerically ascending order
await analysis.analyzeSnapshotsInDirectory(snapshotDir);

The new heap analysis can also be used with analyze, in that case snapshotMapReduce will use all the heap snapshot in alphanumerically ascending order from BrowserInteractionResultReader.

Why not passing in all heap snapshots as an array of IHeapSnapshots? Each heap snapshot could be non-trivial in size, loading them all at once may not be possible.


takeNodeFullHeap()

Take a heap snapshot of the current program state and parse it as IHeapSnapshot. This API also calculates some heap analysis meta data for heap analysis. But this also means slower heap parsing comparing with takeNodeMinimalHeap.

  • Returns: Promise<IHeapSnapshot> | heap representation with heap analysis meta data.

  • Examples:

import type {IHeapSnapshot} from '@memlab/core';
import type {takeNodeFullHeap} from '@memlab/heap-analysis';

(async function () {
const heap: IHeapSnapshot = await takeNodeFullHeap();
})();