@memlab/heap-analysis 1.0.1 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/BaseAnalysis.d.ts +82 -5
- package/dist/BaseAnalysis.js +78 -12
- package/dist/PluginUtils.d.ts +267 -1
- package/dist/PluginUtils.js +269 -3
- package/dist/__tests__/package.test.d.ts +2 -0
- package/dist/__tests__/package.test.js +85 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +27 -5
- package/dist/plugins/CollectionsHoldingStaleAnalysis.d.ts +5 -0
- package/dist/plugins/CollectionsHoldingStaleAnalysis.js +11 -0
- package/dist/plugins/DetachedDOMElementAnalysis.d.ts +5 -0
- package/dist/plugins/DetachedDOMElementAnalysis.js +11 -0
- package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.d.ts +6 -0
- package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.js +13 -0
- package/dist/plugins/ObjectFanoutAnalysis.d.ts +5 -0
- package/dist/plugins/ObjectFanoutAnalysis.js +12 -0
- package/dist/plugins/ObjectShallowAnalysis.d.ts +27 -1
- package/dist/plugins/ObjectShallowAnalysis.js +25 -0
- package/dist/plugins/ObjectShapeAnalysis.d.ts +5 -0
- package/dist/plugins/ObjectShapeAnalysis.js +11 -0
- package/dist/plugins/ObjectSizeAnalysis.d.ts +5 -0
- package/dist/plugins/ObjectSizeAnalysis.js +12 -0
- package/dist/plugins/ObjectUnboundGrowthAnalysis.d.ts +5 -0
- package/dist/plugins/ObjectUnboundGrowthAnalysis.js +11 -0
- package/dist/plugins/ShapeUnboundGrowthAnalysis.d.ts +11 -15
- package/dist/plugins/ShapeUnboundGrowthAnalysis.js +16 -1
- package/dist/plugins/StringAnalysis.d.ts +34 -2
- package/dist/plugins/StringAnalysis.js +32 -3
- package/dist/plugins/UnmountedReactFiberNodesAnalysis.d.ts +5 -0
- package/dist/plugins/UnmountedReactFiberNodesAnalysis.js +11 -0
- package/package.json +3 -2
- package/dist/BaseAnalysis.d.ts.map +0 -1
- package/dist/HeapAnalysisLoader.d.ts.map +0 -1
- package/dist/PluginUtils.d.ts.map +0 -1
- package/dist/__tests__/HeapAnalysis.test.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/options/HeapAnalysisSnapshotDirectoryOption.d.ts.map +0 -1
- package/dist/options/HeapAnalysisSnapshotFileOption.d.ts.map +0 -1
- package/dist/plugins/CollectionsHoldingStaleAnalysis.d.ts.map +0 -1
- package/dist/plugins/DetachedDOMElementAnalysis.d.ts.map +0 -1
- package/dist/plugins/GlobalVariableAnalysis/BuiltInGlobalVariables.d.ts.map +0 -1
- package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.d.ts.map +0 -1
- package/dist/plugins/ObjectFanoutAnalysis.d.ts.map +0 -1
- package/dist/plugins/ObjectShallowAnalysis.d.ts.map +0 -1
- package/dist/plugins/ObjectShapeAnalysis.d.ts.map +0 -1
- package/dist/plugins/ObjectSizeAnalysis.d.ts.map +0 -1
- package/dist/plugins/ObjectUnboundGrowthAnalysis.d.ts.map +0 -1
- package/dist/plugins/ShapeUnboundGrowthAnalysis.d.ts.map +0 -1
- package/dist/plugins/StringAnalysis.d.ts.map +0 -1
- package/dist/plugins/UnmountedReactFiberNodesAnalysis.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
## memlab Heap Analysis
|
|
2
2
|
|
|
3
|
-
This is the memlab heap analysis library. It contains all memlab built-in heap analysis and
|
|
3
|
+
This is the memlab heap analysis library. It contains all memlab built-in heap analysis and
|
|
4
4
|
provides a plugin interface for adding new heap analysis that can be easily added to memlab API and memlab CLI.
|
|
5
5
|
|
|
6
|
-
##
|
|
7
|
-
https://facebookincubator.github.io/memlab
|
|
6
|
+
## Online Resources
|
|
7
|
+
* [Official Website and Demo](https://facebookincubator.github.io/memlab)
|
|
8
|
+
* [Documentation](https://facebookincubator.github.io/memlab/docs/intro)
|
package/dist/BaseAnalysis.d.ts
CHANGED
|
@@ -11,15 +11,92 @@ import type { AnyValue } from '@memlab/core';
|
|
|
11
11
|
import type { HeapAnalysisOptions } from './PluginUtils';
|
|
12
12
|
import { BaseOption } from '@memlab/core';
|
|
13
13
|
declare abstract class Analysis {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
process(_options: HeapAnalysisOptions): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* DO NOT override this method if you are implementing your own analysis
|
|
17
|
+
* by extending {@link BaseAnalysis}.
|
|
18
|
+
* @param options This is the auto-generated arguments passed to all the
|
|
19
|
+
* `process` method that your self-defined heap analysis should implement.
|
|
20
|
+
* You are not supposed to construct instances of this class.
|
|
21
|
+
* @returns any type of value returned from the overridden `process` method
|
|
22
|
+
* of the heap analysis instance. Each heap analysis class can define
|
|
23
|
+
* different return value format.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
run(options?: HeapAnalysisOptions): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Run heap analysis for a single heap snapshot file
|
|
29
|
+
* @param file the absolute path of a `.heapsnapshot` file.
|
|
30
|
+
* @returns this API returns void. To get the analysis results,
|
|
31
|
+
* check out the documentation of the hosting heap analysis class and
|
|
32
|
+
* call the analysis-specific API to get results after calling this method.
|
|
33
|
+
* * **Example**:
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const analysis = new StringAnalysis();
|
|
36
|
+
* await anaysis.analyzeSnapshotFromFile(snapshotFile);
|
|
37
|
+
* const stringPatterns = analysis.getTopDuplicatedStringsInCount();
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
analyzeSnapshotFromFile(file: string): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Run heap analysis for a series of heap snapshot files
|
|
43
|
+
* @param directory the absolute path of the directory holding a series of
|
|
44
|
+
* `.heapsnapshot` files, all snapshot files will be loaded and analyzed
|
|
45
|
+
* in the alphanumerically ascending order of those snapshot file names.
|
|
46
|
+
* @returns this API returns void. To get the analysis results,
|
|
47
|
+
* check out the documentation of the hosting heap analysis class and
|
|
48
|
+
* call the analysis-specific API to get results after calling this method.
|
|
49
|
+
* * **Example**:
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const analysis = new ShapeUnboundGrowthAnalysis();
|
|
52
|
+
* await anaysis.analyzeSnapshotsInDirectory(snapshotDirectory);
|
|
53
|
+
* const shapes = analysis.getShapesWithUnboundGrowth();
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
analyzeSnapshotsInDirectory(directory: string): Promise<void>;
|
|
18
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
*
|
|
60
|
+
*/
|
|
19
61
|
declare class BaseAnalysis extends Analysis {
|
|
62
|
+
/**
|
|
63
|
+
* Get the name of the heap analysis, which is also used to reference
|
|
64
|
+
* the analysis in memlab command-line tool.
|
|
65
|
+
*
|
|
66
|
+
* The following terminal command will initiate with this analysis:
|
|
67
|
+
* `memlab analyze <ANALYSIS_NAME>`
|
|
68
|
+
*
|
|
69
|
+
* @returns the name of the analysis
|
|
70
|
+
* * **Examples**:
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const analysis = new YourAnalysis();
|
|
73
|
+
* const name = analysis.getCommandName();
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
20
76
|
getCommandName(): string;
|
|
77
|
+
/**
|
|
78
|
+
* Get the textual description of the heap analysis.
|
|
79
|
+
* The description of this analysis will be printed by:
|
|
80
|
+
* `memlab analyze list`
|
|
81
|
+
*
|
|
82
|
+
* @returns the description
|
|
83
|
+
*/
|
|
21
84
|
getDescription(): string;
|
|
22
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Callback for `memlab analyze <command-name>`.
|
|
87
|
+
* Do the memory analysis and print results in this callback
|
|
88
|
+
* The analysis should support:
|
|
89
|
+
* 1) printing results on screen
|
|
90
|
+
* 2) returning results via the return value
|
|
91
|
+
* @param options This is the auto-generated arguments passed to all the
|
|
92
|
+
* `process` method that your self-defined heap analysis should implement.
|
|
93
|
+
* You are not supposed to construct instances of this class.
|
|
94
|
+
*/
|
|
95
|
+
process(options: HeapAnalysisOptions): Promise<AnyValue>;
|
|
96
|
+
/**
|
|
97
|
+
* override this method if you would like CLI to print the option info
|
|
98
|
+
* @returns an array of command line options
|
|
99
|
+
*/
|
|
23
100
|
getOptions(): BaseOption[];
|
|
24
101
|
}
|
|
25
102
|
export default BaseAnalysis;
|
package/dist/BaseAnalysis.js
CHANGED
|
@@ -48,13 +48,36 @@ class Analysis {
|
|
|
48
48
|
throw new Error(`${className}.process is not implemented`);
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
/**
|
|
52
|
+
* DO NOT override this method if you are implementing your own analysis
|
|
53
|
+
* by extending {@link BaseAnalysis}.
|
|
54
|
+
* @param options This is the auto-generated arguments passed to all the
|
|
55
|
+
* `process` method that your self-defined heap analysis should implement.
|
|
56
|
+
* You are not supposed to construct instances of this class.
|
|
57
|
+
* @returns any type of value returned from the overridden `process` method
|
|
58
|
+
* of the heap analysis instance. Each heap analysis class can define
|
|
59
|
+
* different return value format.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
52
62
|
run(options = PluginUtils_1.default.defaultAnalysisArgs) {
|
|
53
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54
64
|
loadScenarioConfig();
|
|
55
65
|
return yield this.process(options);
|
|
56
66
|
});
|
|
57
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Run heap analysis for a single heap snapshot file
|
|
70
|
+
* @param file the absolute path of a `.heapsnapshot` file.
|
|
71
|
+
* @returns this API returns void. To get the analysis results,
|
|
72
|
+
* check out the documentation of the hosting heap analysis class and
|
|
73
|
+
* call the analysis-specific API to get results after calling this method.
|
|
74
|
+
* * **Example**:
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const analysis = new StringAnalysis();
|
|
77
|
+
* await anaysis.analyzeSnapshotFromFile(snapshotFile);
|
|
78
|
+
* const stringPatterns = analysis.getTopDuplicatedStringsInCount();
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
58
81
|
analyzeSnapshotFromFile(file) {
|
|
59
82
|
return __awaiter(this, void 0, void 0, function* () {
|
|
60
83
|
return this.process({
|
|
@@ -66,6 +89,21 @@ class Analysis {
|
|
|
66
89
|
});
|
|
67
90
|
});
|
|
68
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Run heap analysis for a series of heap snapshot files
|
|
94
|
+
* @param directory the absolute path of the directory holding a series of
|
|
95
|
+
* `.heapsnapshot` files, all snapshot files will be loaded and analyzed
|
|
96
|
+
* in the alphanumerically ascending order of those snapshot file names.
|
|
97
|
+
* @returns this API returns void. To get the analysis results,
|
|
98
|
+
* check out the documentation of the hosting heap analysis class and
|
|
99
|
+
* call the analysis-specific API to get results after calling this method.
|
|
100
|
+
* * **Example**:
|
|
101
|
+
* ```typescript
|
|
102
|
+
* const analysis = new ShapeUnboundGrowthAnalysis();
|
|
103
|
+
* await anaysis.analyzeSnapshotsInDirectory(snapshotDirectory);
|
|
104
|
+
* const shapes = analysis.getShapesWithUnboundGrowth();
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
69
107
|
analyzeSnapshotsInDirectory(directory) {
|
|
70
108
|
return __awaiter(this, void 0, void 0, function* () {
|
|
71
109
|
return this.process({
|
|
@@ -78,33 +116,61 @@ class Analysis {
|
|
|
78
116
|
});
|
|
79
117
|
}
|
|
80
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
*
|
|
121
|
+
*/
|
|
81
122
|
class BaseAnalysis extends Analysis {
|
|
82
|
-
|
|
83
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Get the name of the heap analysis, which is also used to reference
|
|
125
|
+
* the analysis in memlab command-line tool.
|
|
126
|
+
*
|
|
127
|
+
* The following terminal command will initiate with this analysis:
|
|
128
|
+
* `memlab analyze <ANALYSIS_NAME>`
|
|
129
|
+
*
|
|
130
|
+
* @returns the name of the analysis
|
|
131
|
+
* * **Examples**:
|
|
132
|
+
* ```typescript
|
|
133
|
+
* const analysis = new YourAnalysis();
|
|
134
|
+
* const name = analysis.getCommandName();
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
84
137
|
getCommandName() {
|
|
85
138
|
const className = this.constructor.name;
|
|
86
139
|
throw new Error(`${className}.getCommandName is not implemented`);
|
|
87
140
|
}
|
|
88
|
-
|
|
89
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Get the textual description of the heap analysis.
|
|
143
|
+
* The description of this analysis will be printed by:
|
|
144
|
+
* `memlab analyze list`
|
|
145
|
+
*
|
|
146
|
+
* @returns the description
|
|
147
|
+
*/
|
|
90
148
|
getDescription() {
|
|
91
149
|
const className = this.constructor.name;
|
|
92
150
|
throw new Error(`${className}.getDescription is not implemented`);
|
|
93
151
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Callback for `memlab analyze <command-name>`.
|
|
154
|
+
* Do the memory analysis and print results in this callback
|
|
155
|
+
* The analysis should support:
|
|
156
|
+
* 1) printing results on screen
|
|
157
|
+
* 2) returning results via the return value
|
|
158
|
+
* @param options This is the auto-generated arguments passed to all the
|
|
159
|
+
* `process` method that your self-defined heap analysis should implement.
|
|
160
|
+
* You are not supposed to construct instances of this class.
|
|
161
|
+
*/
|
|
99
162
|
process(
|
|
100
163
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
101
|
-
|
|
164
|
+
options) {
|
|
102
165
|
return __awaiter(this, void 0, void 0, function* () {
|
|
103
166
|
const className = this.constructor.name;
|
|
104
167
|
throw new Error(`${className}.process is not implemented`);
|
|
105
168
|
});
|
|
106
169
|
}
|
|
107
|
-
|
|
170
|
+
/**
|
|
171
|
+
* override this method if you would like CLI to print the option info
|
|
172
|
+
* @returns an array of command line options
|
|
173
|
+
*/
|
|
108
174
|
getOptions() {
|
|
109
175
|
return [];
|
|
110
176
|
}
|
package/dist/PluginUtils.d.ts
CHANGED
|
@@ -9,11 +9,22 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { ParsedArgs } from 'minimist';
|
|
11
11
|
import { IHeapSnapshot, IHeapNode, AnyOptions, IHeapEdge, Nullable, MemLabConfig } from '@memlab/core';
|
|
12
|
+
declare function isNodeWorthInspecting(node: IHeapNode): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* This is the auto-generated arguments passed to all the `process` method
|
|
15
|
+
* that your self-defined heap analysis should implement.
|
|
16
|
+
* You are not supposed to construct instances of this class.
|
|
17
|
+
*
|
|
18
|
+
* For code examples on how this options could be used, see
|
|
19
|
+
* {@link getSnapshotFileForAnalysis}, {@link loadHeapSnapshot},
|
|
20
|
+
* or {@link snapshotMapReduce}.
|
|
21
|
+
*/
|
|
12
22
|
export declare type HeapAnalysisOptions = {
|
|
23
|
+
/** @internal */
|
|
13
24
|
args: ParsedArgs;
|
|
25
|
+
/** @internal */
|
|
14
26
|
config?: MemLabConfig;
|
|
15
27
|
};
|
|
16
|
-
declare function isNodeWorthInspecting(node: IHeapNode): boolean;
|
|
17
28
|
declare type PrintNodeOption = {
|
|
18
29
|
indent?: string;
|
|
19
30
|
printReferences?: boolean;
|
|
@@ -21,11 +32,264 @@ declare type PrintNodeOption = {
|
|
|
21
32
|
declare function printNodeListInTerminal(nodeList: IHeapNode[], options?: AnyOptions & PrintNodeOption): void;
|
|
22
33
|
declare function printReferencesInTerminal(edgeList: IHeapEdge[], options?: AnyOptions & PrintNodeOption): void;
|
|
23
34
|
declare function getObjectOutgoingEdgeCount(node: IHeapNode): number;
|
|
35
|
+
/**
|
|
36
|
+
* Get the heap snapshot file's absolute path passed to the hosting heap
|
|
37
|
+
* analysis via `HeapAnalysisOptions`.
|
|
38
|
+
*
|
|
39
|
+
* This API is supposed to be used within the overridden `process` method
|
|
40
|
+
* of an `BaseAnalysis` instance.
|
|
41
|
+
*
|
|
42
|
+
* @param options this is the auto-generated input passed to all the `BaseAnalysis` instances
|
|
43
|
+
* @returns the absolute path of the heap snapshot file
|
|
44
|
+
* * **Examples:**
|
|
45
|
+
* ```typescript
|
|
46
|
+
* import type {IHeapSnapshot} from '@memlab/core';
|
|
47
|
+
* import type {HeapAnalysisOptions} from '@memlab/heap-analysis';
|
|
48
|
+
* import {getSnapshotFileForAnalysis, BaseAnalysis} from '@memlab/heap-analysis';
|
|
49
|
+
*
|
|
50
|
+
* class ExampleAnalysis extends BaseAnalysis {
|
|
51
|
+
* public getCommandName(): string {
|
|
52
|
+
* return 'example-analysis';
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* public getDescription(): string {
|
|
56
|
+
* return 'an example analysis for demo';
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* async process(options: HeapAnalysisOptions): Promise<void> {
|
|
60
|
+
* const file = getSnapshotFileForAnalysis(options);
|
|
61
|
+
* }
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* Use the following code to invoke the heap analysis:
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const analysis = new ExampleAnalysis();
|
|
68
|
+
* // any .heapsnapshot file recorded by memlab or saved manually from Chrome
|
|
69
|
+
* await analysis.analyzeSnapshotFromFile(snapshotFile);
|
|
70
|
+
* ```
|
|
71
|
+
* The new heap analysis can also be used with {@link analyze}, in that case
|
|
72
|
+
* `getSnapshotFileForAnalysis` will use the last heap snapshot in alphanumerically
|
|
73
|
+
* ascending order from {@link BrowserInteractionResultReader}.
|
|
74
|
+
*/
|
|
24
75
|
declare function getSnapshotFileForAnalysis(options: HeapAnalysisOptions): string;
|
|
76
|
+
/**
|
|
77
|
+
* Get the absolute path of the directory holding all the heap snapshot files
|
|
78
|
+
* passed to the hosting heap analysis via `HeapAnalysisOptions`.
|
|
79
|
+
*
|
|
80
|
+
* This API is supposed to be used within the overridden `process` method
|
|
81
|
+
* of an `BaseAnalysis` instance.
|
|
82
|
+
*
|
|
83
|
+
* @param options this is the auto-generated input passed
|
|
84
|
+
* to all the `BaseAnalysis` instances
|
|
85
|
+
* @returns the absolute path of the directory
|
|
86
|
+
* * **Examples:**
|
|
87
|
+
* ```typescript
|
|
88
|
+
* import type {IHeapSnapshot} from '@memlab/core';
|
|
89
|
+
* import type {HeapAnalysisOptions} from '@memlab/heap-analysis';
|
|
90
|
+
* import {getSnapshotFileForAnalysis, BaseAnalysis} from '@memlab/heap-analysis';
|
|
91
|
+
*
|
|
92
|
+
* class ExampleAnalysis extends BaseAnalysis {
|
|
93
|
+
* public getCommandName(): string {
|
|
94
|
+
* return 'example-analysis';
|
|
95
|
+
* }
|
|
96
|
+
*
|
|
97
|
+
* public getDescription(): string {
|
|
98
|
+
* return 'an example analysis for demo';
|
|
99
|
+
* }
|
|
100
|
+
*
|
|
101
|
+
* async process(options: HeapAnalysisOptions): Promise<void> {
|
|
102
|
+
* const directory = getSnapshotDirForAnalysis(options);
|
|
103
|
+
* }
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* Use the following code to invoke the heap analysis:
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const analysis = new ExampleAnalysis();
|
|
110
|
+
* // any .heapsnapshot file recorded by memlab or saved manually from Chrome
|
|
111
|
+
* await analysis.analyzeSnapshotFromFile(snapshotFile);
|
|
112
|
+
* ```
|
|
113
|
+
* The new heap analysis can also be used with {@link analyze}, in that case
|
|
114
|
+
* `getSnapshotDirForAnalysis` use the snapshot directory from
|
|
115
|
+
* {@link BrowserInteractionResultReader}.
|
|
116
|
+
*/
|
|
25
117
|
declare function getSnapshotDirForAnalysis(options: HeapAnalysisOptions): Nullable<string>;
|
|
118
|
+
/**
|
|
119
|
+
* Load the heap graph based on the single JavaScript heap snapshot
|
|
120
|
+
* passed to the hosting heap analysis via `HeapAnalysisOptions`.
|
|
121
|
+
*
|
|
122
|
+
* This API is supposed to be used within the `process` implementation
|
|
123
|
+
* of an `BaseAnalysis` instance.
|
|
124
|
+
*
|
|
125
|
+
* @param options this is the auto-generated input passed to all the `BaseAnalysis` instances
|
|
126
|
+
* @returns the graph representation of the heap
|
|
127
|
+
* * **Examples:**
|
|
128
|
+
* ```typescript
|
|
129
|
+
* import type {IHeapSnapshot} from '@memlab/core';
|
|
130
|
+
* import type {HeapAnalysisOptions} from '@memlab/heap-analysis';
|
|
131
|
+
* import {loadHeapSnapshot, BaseAnalysis} from '@memlab/heap-analysis';
|
|
132
|
+
*
|
|
133
|
+
* class ExampleAnalysis extends BaseAnalysis {
|
|
134
|
+
* public getCommandName(): string {
|
|
135
|
+
* return 'example-analysis';
|
|
136
|
+
* }
|
|
137
|
+
*
|
|
138
|
+
* public getDescription(): string {
|
|
139
|
+
* return 'an example analysis for demo';
|
|
140
|
+
* }
|
|
141
|
+
*
|
|
142
|
+
* async process(options: HeapAnalysisOptions): Promise<void> {
|
|
143
|
+
* const heap = await loadHeapSnapshot(options);
|
|
144
|
+
* // doing heap analysis
|
|
145
|
+
* }
|
|
146
|
+
* }
|
|
147
|
+
* ```
|
|
148
|
+
*
|
|
149
|
+
* Use the following code to invoke the heap analysis:
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const analysis = new ExampleAnalysis();
|
|
152
|
+
* // any .heapsnapshot file recorded by memlab or saved manually from Chrome
|
|
153
|
+
* await analysis.analyzeSnapshotFromFile(snapshotFile);
|
|
154
|
+
* ```
|
|
155
|
+
* The new heap analysis can also be used with {@link analyze}, in that case
|
|
156
|
+
* `loadHeapSnapshot` will use the last heap snapshot in alphanumerically
|
|
157
|
+
* ascending order from {@link BrowserInteractionResultReader}.
|
|
158
|
+
*/
|
|
26
159
|
declare function loadHeapSnapshot(options: HeapAnalysisOptions): Promise<IHeapSnapshot>;
|
|
160
|
+
/**
|
|
161
|
+
* Load and parse a `.heapsnapshot` file and calculate meta data like
|
|
162
|
+
* dominator nodes and retained sizes.
|
|
163
|
+
* @param file the absolute path of the `.heapsnapshot` file
|
|
164
|
+
* @returns the heap graph representation instance that supports querying
|
|
165
|
+
* the heap
|
|
166
|
+
* * **Examples**:
|
|
167
|
+
* ```typescript
|
|
168
|
+
* import {dumpNodeHeapSnapshot} from '@memlab/core';
|
|
169
|
+
* import {getHeapFromFile} from '@memlab/heap-analysis';
|
|
170
|
+
*
|
|
171
|
+
* (async function (){
|
|
172
|
+
* const heapFile = dumpNodeHeapSnapshot();
|
|
173
|
+
* const heap = await getHeapFromFile(heapFile);
|
|
174
|
+
* })();
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
declare function getHeapFromFile(file: string): Promise<IHeapSnapshot>;
|
|
178
|
+
/**
|
|
179
|
+
* When a heap analysis is taking multiple heap snapshots as input for memory
|
|
180
|
+
* analysis (e.g., finding which object keeps growing in size in a series of
|
|
181
|
+
* heap snapshots), this API could be used to do
|
|
182
|
+
* [MapRedue](https://en.wikipedia.org/wiki/MapReduce) on all heap snapshots.
|
|
183
|
+
*
|
|
184
|
+
* This API is supposed to be used within the `process` implementation
|
|
185
|
+
* of an `BaseAnalysis` instance that is designed to analyze multiple heap
|
|
186
|
+
* snapshots (as an example, finding which object keeps growing overtime)
|
|
187
|
+
*
|
|
188
|
+
* @param mapCallback the map function in MapReduce, the function will be applied
|
|
189
|
+
* to each heap snapshot
|
|
190
|
+
* @param reduceCallback the reduce function in MapReduce, the function will take
|
|
191
|
+
* as input all intermediate results from all map function calls
|
|
192
|
+
* @typeParam T1 - the type of the intermediate result from each map function call
|
|
193
|
+
* @typeParam T2 - the type of the final result of the reduce function call
|
|
194
|
+
* @param options this is the auto-generated input passed to all the `BaseAnalysis` instances
|
|
195
|
+
* @returns the return value of your reduce function
|
|
196
|
+
* * **Examples:**
|
|
197
|
+
* ```typescript
|
|
198
|
+
* import type {IHeapSnapshot} from '@memlab/core';
|
|
199
|
+
* import type {HeapAnalysisOptions} from '@memlab/heap-analysis';
|
|
200
|
+
* import {snapshotMapReduce, BaseAnalysis} from '@memlab/heap-analysis';
|
|
201
|
+
*
|
|
202
|
+
* class ExampleAnalysis extends BaseAnalysis {
|
|
203
|
+
* public getCommandName(): string {
|
|
204
|
+
* return 'example-analysis';
|
|
205
|
+
* }
|
|
206
|
+
*
|
|
207
|
+
* public getDescription(): string {
|
|
208
|
+
* return 'an example analysis for demo';
|
|
209
|
+
* }
|
|
210
|
+
*
|
|
211
|
+
* async process(options: HeapAnalysisOptions): Promise<void> {
|
|
212
|
+
* // check if the number of heap objects keeps growing overtime
|
|
213
|
+
* const isMonotonicIncreasing = await snapshotMapReduce(
|
|
214
|
+
* (heap) => heap.nodes.length,
|
|
215
|
+
* (nodeCounts) =>
|
|
216
|
+
* nodeCounts[0] < nodeCounts[nodeCounts.length - 1] &&
|
|
217
|
+
* nodeCounts.every((count, i) => i === 0 || count >= nodeCounts[i - 1]),
|
|
218
|
+
* options,
|
|
219
|
+
* );
|
|
220
|
+
* }
|
|
221
|
+
* }
|
|
222
|
+
* ```
|
|
223
|
+
*
|
|
224
|
+
* Use the following code to invoke the heap analysis:
|
|
225
|
+
* ```typescript
|
|
226
|
+
* const analysis = new ExampleAnalysis();
|
|
227
|
+
* // snapshotDir includes a series of .heapsnapshot files recorded by
|
|
228
|
+
* // memlab or saved manually from Chrome, those files will be loaded
|
|
229
|
+
* // in alphanumerically asceneding order
|
|
230
|
+
* await analysis.analyzeSnapshotsInDirectory(snapshotDir);
|
|
231
|
+
* ```
|
|
232
|
+
* The new heap analysis can also be used with {@link analyze}, in that case
|
|
233
|
+
* `snapshotMapReduce` will use all the heap snapshot in alphanumerically
|
|
234
|
+
* ascending order from {@link BrowserInteractionResultReader}.
|
|
235
|
+
*
|
|
236
|
+
* **Why not passing in all heap snapshots as an array of {@link IHeapSnapshot}s?**
|
|
237
|
+
* Each heap snapshot could be non-trivial in size, loading them all at once
|
|
238
|
+
* may not be possible.
|
|
239
|
+
*/
|
|
27
240
|
declare function snapshotMapReduce<T1, T2>(mapCallback: (snapshot: IHeapSnapshot, i: number, file: string) => T1, reduceCallback: (results: T1[]) => T2, options: HeapAnalysisOptions): Promise<T2>;
|
|
241
|
+
/**
|
|
242
|
+
* This API aggregates metrics from the
|
|
243
|
+
* [dominator nodes](https://firefox-source-docs.mozilla.org/devtools-user/memory/dominators/index.html)
|
|
244
|
+
* of the set of input heap objects.
|
|
245
|
+
*
|
|
246
|
+
* @param ids Set of ids of heap objects (or nodes)
|
|
247
|
+
* @param snapshot heap graph loaded from a heap snapshot
|
|
248
|
+
* @param checkNodeCb filter callback to exclude some heap object/nodes
|
|
249
|
+
* before calculating the dominator nodes
|
|
250
|
+
* @param nodeMetricsCb callback to calculate metrics from each dominator node
|
|
251
|
+
* @returns the aggregated metrics
|
|
252
|
+
*/
|
|
28
253
|
declare function aggregateDominatorMetrics(ids: Set<number>, snapshot: IHeapSnapshot, checkNodeCb: (node: IHeapNode) => boolean, nodeMetricsCb: (node: IHeapNode) => number): number;
|
|
254
|
+
/**
|
|
255
|
+
* This API calculate the set of
|
|
256
|
+
* [dominator nodes](https://firefox-source-docs.mozilla.org/devtools-user/memory/dominators/index.html)
|
|
257
|
+
* of the set of input heap objects.
|
|
258
|
+
* @param ids Set of ids of heap objects (or nodes)
|
|
259
|
+
* @param snapshot heap loaded from a heap snapshot
|
|
260
|
+
* @returns the set of dominator nodes/objects
|
|
261
|
+
* * * **Examples**:
|
|
262
|
+
* ```typescript
|
|
263
|
+
* import {dumpNodeHeapSnapshot} from '@memlab/core';
|
|
264
|
+
* import {getHeapFromFile, getDominatorNodes} from '@memlab/heap-analysis';
|
|
265
|
+
*
|
|
266
|
+
* class TestObject {}
|
|
267
|
+
*
|
|
268
|
+
* (async function () {
|
|
269
|
+
* const t1 = new TestObject();
|
|
270
|
+
* const t2 = new TestObject();
|
|
271
|
+
*
|
|
272
|
+
* // dump the heap of this running JavaScript program
|
|
273
|
+
* const heapFile = dumpNodeHeapSnapshot();
|
|
274
|
+
* const heap = await getHeapFromFile(heapFile);
|
|
275
|
+
*
|
|
276
|
+
* // find the heap node for TestObject
|
|
277
|
+
* let nodes = [];
|
|
278
|
+
* heap.nodes.forEach(node => {
|
|
279
|
+
* if (node.name === 'TestObject' && node.type === 'object') {
|
|
280
|
+
* nodes.push(node);
|
|
281
|
+
* }
|
|
282
|
+
* });
|
|
283
|
+
*
|
|
284
|
+
* // get the dominator nodes
|
|
285
|
+
* const dominatorIds = getDominatorNodes(
|
|
286
|
+
* new Set(nodes.map(node => node.id)),
|
|
287
|
+
* heap,
|
|
288
|
+
* );
|
|
289
|
+
* })();
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
declare function getDominatorNodes(ids: Set<number>, snapshot: IHeapSnapshot): Set<number>;
|
|
29
293
|
declare function filterOutLargestObjects(snapshot: IHeapSnapshot, objectFilter: (node: IHeapNode) => boolean, listSize?: number): IHeapNode[];
|
|
30
294
|
declare const _default: {
|
|
31
295
|
aggregateDominatorMetrics: typeof aggregateDominatorMetrics;
|
|
@@ -35,11 +299,13 @@ declare const _default: {
|
|
|
35
299
|
};
|
|
36
300
|
};
|
|
37
301
|
filterOutLargestObjects: typeof filterOutLargestObjects;
|
|
302
|
+
getDominatorNodes: typeof getDominatorNodes;
|
|
38
303
|
getObjectOutgoingEdgeCount: typeof getObjectOutgoingEdgeCount;
|
|
39
304
|
getSnapshotDirForAnalysis: typeof getSnapshotDirForAnalysis;
|
|
40
305
|
getSnapshotFileForAnalysis: typeof getSnapshotFileForAnalysis;
|
|
41
306
|
isNodeWorthInspecting: typeof isNodeWorthInspecting;
|
|
42
307
|
loadHeapSnapshot: typeof loadHeapSnapshot;
|
|
308
|
+
getHeapFromFile: typeof getHeapFromFile;
|
|
43
309
|
printNodeListInTerminal: typeof printNodeListInTerminal;
|
|
44
310
|
printReferencesInTerminal: typeof printReferencesInTerminal;
|
|
45
311
|
snapshotMapReduce: typeof snapshotMapReduce;
|