@memlab/heap-analysis 1.0.0
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 +11 -0
- package/dist/BaseAnalysis.d.ts +26 -0
- package/dist/BaseAnalysis.d.ts.map +1 -0
- package/dist/BaseAnalysis.js +112 -0
- package/dist/HeapAnalysisLoader.d.ts +19 -0
- package/dist/HeapAnalysisLoader.d.ts.map +1 -0
- package/dist/HeapAnalysisLoader.js +59 -0
- package/dist/PluginUtils.d.ts +48 -0
- package/dist/PluginUtils.d.ts.map +1 -0
- package/dist/PluginUtils.js +283 -0
- package/dist/__tests__/HeapAnalysis.test.d.ts +11 -0
- package/dist/__tests__/HeapAnalysis.test.d.ts.map +1 -0
- package/dist/__tests__/HeapAnalysis.test.js +32 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/options/HeapAnalysisSnapshotDirectoryOption.d.ts +18 -0
- package/dist/options/HeapAnalysisSnapshotDirectoryOption.d.ts.map +1 -0
- package/dist/options/HeapAnalysisSnapshotDirectoryOption.js +50 -0
- package/dist/options/HeapAnalysisSnapshotFileOption.d.ts +18 -0
- package/dist/options/HeapAnalysisSnapshotFileOption.d.ts.map +1 -0
- package/dist/options/HeapAnalysisSnapshotFileOption.js +50 -0
- package/dist/plugins/CollectionsHoldingStaleAnalysis.d.ts +22 -0
- package/dist/plugins/CollectionsHoldingStaleAnalysis.d.ts.map +1 -0
- package/dist/plugins/CollectionsHoldingStaleAnalysis.js +132 -0
- package/dist/plugins/DetachedDOMElementAnalysis.d.ts +22 -0
- package/dist/plugins/DetachedDOMElementAnalysis.d.ts.map +1 -0
- package/dist/plugins/DetachedDOMElementAnalysis.js +53 -0
- package/dist/plugins/GlobalVariableAnalysis/BuiltInGlobalVariables.d.ts +13 -0
- package/dist/plugins/GlobalVariableAnalysis/BuiltInGlobalVariables.d.ts.map +1 -0
- package/dist/plugins/GlobalVariableAnalysis/BuiltInGlobalVariables.js +1073 -0
- package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.d.ts +22 -0
- package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.d.ts.map +1 -0
- package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.js +78 -0
- package/dist/plugins/ObjectFanoutAnalysis.d.ts +21 -0
- package/dist/plugins/ObjectFanoutAnalysis.d.ts.map +1 -0
- package/dist/plugins/ObjectFanoutAnalysis.js +69 -0
- package/dist/plugins/ObjectShallowAnalysis.d.ts +42 -0
- package/dist/plugins/ObjectShallowAnalysis.d.ts.map +1 -0
- package/dist/plugins/ObjectShallowAnalysis.js +233 -0
- package/dist/plugins/ObjectShapeAnalysis.d.ts +20 -0
- package/dist/plugins/ObjectShapeAnalysis.d.ts.map +1 -0
- package/dist/plugins/ObjectShapeAnalysis.js +45 -0
- package/dist/plugins/ObjectSizeAnalysis.d.ts +20 -0
- package/dist/plugins/ObjectSizeAnalysis.d.ts.map +1 -0
- package/dist/plugins/ObjectSizeAnalysis.js +45 -0
- package/dist/plugins/ObjectUnboundGrowthAnalysis.d.ts +20 -0
- package/dist/plugins/ObjectUnboundGrowthAnalysis.d.ts.map +1 -0
- package/dist/plugins/ObjectUnboundGrowthAnalysis.js +47 -0
- package/dist/plugins/ShapeUnboundGrowthAnalysis.d.ts +42 -0
- package/dist/plugins/ShapeUnboundGrowthAnalysis.d.ts.map +1 -0
- package/dist/plugins/ShapeUnboundGrowthAnalysis.js +164 -0
- package/dist/plugins/StringAnalysis.d.ts +40 -0
- package/dist/plugins/StringAnalysis.d.ts.map +1 -0
- package/dist/plugins/StringAnalysis.js +217 -0
- package/dist/plugins/UnmountedReactFiberNodesAnalysis.d.ts +19 -0
- package/dist/plugins/UnmountedReactFiberNodesAnalysis.d.ts.map +1 -0
- package/dist/plugins/UnmountedReactFiberNodesAnalysis.js +46 -0
- package/package.json +55 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import type { HeapAnalysisOptions } from '../../PluginUtils';
|
|
11
|
+
import { BaseOption } from '@memlab/core';
|
|
12
|
+
import BaseAnalysis from '../../BaseAnalysis';
|
|
13
|
+
declare class GlobalVariableAnalysis extends BaseAnalysis {
|
|
14
|
+
getCommandName(): string;
|
|
15
|
+
getDescription(): string;
|
|
16
|
+
getOptions(): BaseOption[];
|
|
17
|
+
process(options: HeapAnalysisOptions): Promise<void>;
|
|
18
|
+
private shouldFilterOutEdge;
|
|
19
|
+
private getGlobalVariables;
|
|
20
|
+
}
|
|
21
|
+
export default GlobalVariableAnalysis;
|
|
22
|
+
//# sourceMappingURL=GlobalVariableAnalysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GlobalVariableAnalysis.d.ts","sourceRoot":"","sources":["../../../src/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAExC,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAI9C,cAAM,sBAAuB,SAAQ,YAAY;IAC/C,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,UAAU,IAAI,UAAU,EAAE;IAIpB,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1D,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,kBAAkB;CAoB3B;AAED,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const HeapAnalysisSnapshotFileOption_1 = __importDefault(require("../../options/HeapAnalysisSnapshotFileOption"));
|
|
25
|
+
const BaseAnalysis_1 = __importDefault(require("../../BaseAnalysis"));
|
|
26
|
+
const PluginUtils_1 = __importDefault(require("../../PluginUtils"));
|
|
27
|
+
const BuiltInGlobalVariables_1 = __importDefault(require("./BuiltInGlobalVariables"));
|
|
28
|
+
class GlobalVariableAnalysis extends BaseAnalysis_1.default {
|
|
29
|
+
getCommandName() {
|
|
30
|
+
return 'global-variable';
|
|
31
|
+
}
|
|
32
|
+
getDescription() {
|
|
33
|
+
return 'Get global variables in heap';
|
|
34
|
+
}
|
|
35
|
+
getOptions() {
|
|
36
|
+
return [new HeapAnalysisSnapshotFileOption_1.default()];
|
|
37
|
+
}
|
|
38
|
+
process(options) {
|
|
39
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
const snapshot = yield PluginUtils_1.default.loadHeapSnapshot(options);
|
|
41
|
+
const list = this.getGlobalVariables(snapshot);
|
|
42
|
+
PluginUtils_1.default.printReferencesInTerminal(list);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
shouldFilterOutEdge(edge) {
|
|
46
|
+
if (BuiltInGlobalVariables_1.default.has(`${edge.name_or_index}`)) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
const toNodeType = edge.toNode.type;
|
|
50
|
+
if (edge.name_or_index === '<symbol>') {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (toNodeType === 'hidden' ||
|
|
54
|
+
toNodeType === 'array' ||
|
|
55
|
+
toNodeType === 'number') {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
getGlobalVariables(snapshot) {
|
|
61
|
+
// rank heap objects based on fanout
|
|
62
|
+
const ret = [];
|
|
63
|
+
const processNode = (node) => {
|
|
64
|
+
if (!node.name.startsWith('Window ')) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const refs = node.references;
|
|
68
|
+
for (const edge of refs) {
|
|
69
|
+
if (!this.shouldFilterOutEdge(edge)) {
|
|
70
|
+
ret.push(edge);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
snapshot.nodes.forEach(processNode);
|
|
75
|
+
return ret.sort((e1, e2) => e2.toNode.retainedSize - e1.toNode.retainedSize);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.default = GlobalVariableAnalysis;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import type { HeapAnalysisOptions } from '../PluginUtils';
|
|
11
|
+
import { BaseOption } from '@memlab/core';
|
|
12
|
+
import BaseAnalysis from '../BaseAnalysis';
|
|
13
|
+
declare class ObjectFanoutAnalysis extends BaseAnalysis {
|
|
14
|
+
getCommandName(): string;
|
|
15
|
+
getDescription(): string;
|
|
16
|
+
getOptions(): BaseOption[];
|
|
17
|
+
process(options: HeapAnalysisOptions): Promise<void>;
|
|
18
|
+
private getObjectsWithHighFanout;
|
|
19
|
+
}
|
|
20
|
+
export default ObjectFanoutAnalysis;
|
|
21
|
+
//# sourceMappingURL=ObjectFanoutAnalysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ObjectFanoutAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/ObjectFanoutAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAIxD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAI3C,cAAM,oBAAqB,SAAQ,YAAY;IAC7C,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,UAAU,IAAI,UAAU,EAAE;IAIpB,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1D,OAAO,CAAC,wBAAwB;CA2BjC;AAED,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const BaseAnalysis_1 = __importDefault(require("../BaseAnalysis"));
|
|
25
|
+
const PluginUtils_1 = __importDefault(require("../PluginUtils"));
|
|
26
|
+
const HeapAnalysisSnapshotFileOption_1 = __importDefault(require("../options/HeapAnalysisSnapshotFileOption"));
|
|
27
|
+
class ObjectFanoutAnalysis extends BaseAnalysis_1.default {
|
|
28
|
+
getCommandName() {
|
|
29
|
+
return 'object-fanout';
|
|
30
|
+
}
|
|
31
|
+
getDescription() {
|
|
32
|
+
return 'Get objects with the most out-going references in heap';
|
|
33
|
+
}
|
|
34
|
+
getOptions() {
|
|
35
|
+
return [new HeapAnalysisSnapshotFileOption_1.default()];
|
|
36
|
+
}
|
|
37
|
+
process(options) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const snapshot = yield PluginUtils_1.default.loadHeapSnapshot(options);
|
|
40
|
+
const list = this.getObjectsWithHighFanout(snapshot, options.args);
|
|
41
|
+
PluginUtils_1.default.printNodeListInTerminal(list);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
getObjectsWithHighFanout(snapshot, args) {
|
|
45
|
+
// rank heap objects based on fanout
|
|
46
|
+
let ret = [];
|
|
47
|
+
const listSize = args.listSize || 20;
|
|
48
|
+
snapshot.nodes.forEach(node => {
|
|
49
|
+
if (!PluginUtils_1.default.isNodeWorthInspecting(node)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const count = PluginUtils_1.default.getObjectOutgoingEdgeCount(node);
|
|
53
|
+
let i;
|
|
54
|
+
for (i = ret.length - 1; i >= 0; --i) {
|
|
55
|
+
const curCnt = PluginUtils_1.default.getObjectOutgoingEdgeCount(ret[i]);
|
|
56
|
+
if (curCnt >= count) {
|
|
57
|
+
ret.splice(i + 1, 0, node);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (i < 0) {
|
|
62
|
+
ret.unshift(node);
|
|
63
|
+
}
|
|
64
|
+
ret = ret.slice(0, listSize);
|
|
65
|
+
});
|
|
66
|
+
return ret;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.default = ObjectFanoutAnalysis;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import type { HeapAnalysisOptions } from '../PluginUtils';
|
|
11
|
+
import { BaseOption } from '@memlab/core';
|
|
12
|
+
import BaseAnalysis from '../BaseAnalysis';
|
|
13
|
+
declare type ObjectRecord = {
|
|
14
|
+
n: number;
|
|
15
|
+
size: number;
|
|
16
|
+
ids: string[];
|
|
17
|
+
obj: string;
|
|
18
|
+
};
|
|
19
|
+
declare class ObjectShallowAnalysis extends BaseAnalysis {
|
|
20
|
+
private topDupObjInCnt;
|
|
21
|
+
private topDupObjInCntListSize;
|
|
22
|
+
private topDupObjInSize;
|
|
23
|
+
private topDupObjInSizeListSize;
|
|
24
|
+
private objectPatternsStat;
|
|
25
|
+
getCommandName(): string;
|
|
26
|
+
getDescription(): string;
|
|
27
|
+
getOptions(): BaseOption[];
|
|
28
|
+
process(options: HeapAnalysisOptions): Promise<void>;
|
|
29
|
+
getTopDuplicatedObjectInCount(): ObjectRecord[];
|
|
30
|
+
private getPreprocessedObjectMap;
|
|
31
|
+
private nodeToObject;
|
|
32
|
+
private static objectPatternsToObserve;
|
|
33
|
+
private shouldIgnoreNode;
|
|
34
|
+
private textEllipsis;
|
|
35
|
+
private rankRecords;
|
|
36
|
+
private calculateTopDuplicatedObjectsInCount;
|
|
37
|
+
private calculateTopDuplicatedObjectsInSize;
|
|
38
|
+
private calculateobjectPatternsStatistics;
|
|
39
|
+
private print;
|
|
40
|
+
}
|
|
41
|
+
export default ObjectShallowAnalysis;
|
|
42
|
+
//# sourceMappingURL=ObjectShallowAnalysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ObjectShallowAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/ObjectShallowAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAGxD,OAAO,EAAc,UAAU,EAAY,MAAM,cAAc,CAAC;AAChE,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAS3C,aAAK,YAAY,GAAG;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAiBF,cAAM,qBAAsB,SAAQ,YAAY;IAC9C,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,sBAAsB,CAAM;IACpC,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,uBAAuB,CAAM;IACrC,OAAO,CAAC,kBAAkB,CAAyB;IAEnD,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,UAAU,IAAI,UAAU,EAAE;IAIpB,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IASnD,6BAA6B,IAAI,YAAY,EAAE;IAItD,OAAO,CAAC,wBAAwB;IAyBhC,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAGpC;IAEF,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,YAAY;IAiBpB,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,oCAAoC;IAS5C,OAAO,CAAC,mCAAmC;IAS3C,OAAO,CAAC,iCAAiC;IA6BzC,OAAO,CAAC,KAAK;CA8Cd;AAED,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
25
|
+
const core_1 = require("@memlab/core");
|
|
26
|
+
const BaseAnalysis_1 = __importDefault(require("../BaseAnalysis"));
|
|
27
|
+
const PluginUtils_1 = __importDefault(require("../PluginUtils"));
|
|
28
|
+
const HeapAnalysisSnapshotFileOption_1 = __importDefault(require("../options/HeapAnalysisSnapshotFileOption"));
|
|
29
|
+
class ObjectShallowAnalysis extends BaseAnalysis_1.default {
|
|
30
|
+
constructor() {
|
|
31
|
+
super(...arguments);
|
|
32
|
+
this.topDupObjInCnt = [];
|
|
33
|
+
this.topDupObjInCntListSize = 10;
|
|
34
|
+
this.topDupObjInSize = [];
|
|
35
|
+
this.topDupObjInSizeListSize = 10;
|
|
36
|
+
this.objectPatternsStat = {};
|
|
37
|
+
}
|
|
38
|
+
getCommandName() {
|
|
39
|
+
return 'object-shallow';
|
|
40
|
+
}
|
|
41
|
+
getDescription() {
|
|
42
|
+
return 'Get objects by key and value, without recursing into sub-objects';
|
|
43
|
+
}
|
|
44
|
+
getOptions() {
|
|
45
|
+
return [new HeapAnalysisSnapshotFileOption_1.default()];
|
|
46
|
+
}
|
|
47
|
+
process(options) {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
const snapshot = yield PluginUtils_1.default.loadHeapSnapshot(options);
|
|
50
|
+
const objectMap = this.getPreprocessedObjectMap(snapshot);
|
|
51
|
+
this.calculateobjectPatternsStatistics(objectMap);
|
|
52
|
+
this.calculateTopDuplicatedObjectsInCount(objectMap);
|
|
53
|
+
this.calculateTopDuplicatedObjectsInSize(objectMap);
|
|
54
|
+
this.print();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
getTopDuplicatedObjectInCount() {
|
|
58
|
+
return this.topDupObjInCnt;
|
|
59
|
+
}
|
|
60
|
+
getPreprocessedObjectMap(snapshot) {
|
|
61
|
+
core_1.info.overwrite('building object map...');
|
|
62
|
+
const objectMap = Object.create(null);
|
|
63
|
+
snapshot.nodes.forEach((node) => {
|
|
64
|
+
if (this.shouldIgnoreNode(node)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const obj = this.nodeToObject(node);
|
|
68
|
+
const value = JSON.stringify(obj);
|
|
69
|
+
objectMap[value] = objectMap[value] || {
|
|
70
|
+
n: 0,
|
|
71
|
+
size: 0,
|
|
72
|
+
ids: [],
|
|
73
|
+
obj: JSON.stringify(obj),
|
|
74
|
+
};
|
|
75
|
+
const record = objectMap[value];
|
|
76
|
+
++record.n;
|
|
77
|
+
record.size += node.retainedSize;
|
|
78
|
+
record.ids.push(node.id);
|
|
79
|
+
});
|
|
80
|
+
return objectMap;
|
|
81
|
+
}
|
|
82
|
+
nodeToObject(node) {
|
|
83
|
+
const result = {};
|
|
84
|
+
for (const edge of node.references) {
|
|
85
|
+
if (edge.type === 'property' && edge.name_or_index != '__proto__') {
|
|
86
|
+
const key = edge.name_or_index;
|
|
87
|
+
const value = edge.toNode;
|
|
88
|
+
if (core_1.utils.isStringNode(value)) {
|
|
89
|
+
result[key] = core_1.utils.getStringNodeValue(edge.toNode);
|
|
90
|
+
}
|
|
91
|
+
else if (value.type === 'number') {
|
|
92
|
+
result[key] = core_1.utils.getNumberNodeValue(edge.toNode);
|
|
93
|
+
}
|
|
94
|
+
else if (value.type === 'boolean') {
|
|
95
|
+
result[key] = core_1.utils.getBooleanNodeValue(edge.toNode);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// shallow analysis, just put the id as a string
|
|
99
|
+
result[key] = 'REFERENCE_' + value.id;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return { class: node.name, object: result };
|
|
104
|
+
}
|
|
105
|
+
shouldIgnoreNode(node) {
|
|
106
|
+
let hasAHiddenReferrer = false;
|
|
107
|
+
node.forEachReferrer((edge) => {
|
|
108
|
+
if (edge.type === 'hidden') {
|
|
109
|
+
hasAHiddenReferrer = true;
|
|
110
|
+
return { stop: true };
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
return !(!hasAHiddenReferrer &&
|
|
114
|
+
node.type === 'object' &&
|
|
115
|
+
node.name !== 'Array' &&
|
|
116
|
+
node.name !== 'ArrayBuffer' &&
|
|
117
|
+
node.name !== 'Set' &&
|
|
118
|
+
node.name !== 'Map' &&
|
|
119
|
+
!node.name.startsWith('Window') &&
|
|
120
|
+
!node.name.startsWith('system /'));
|
|
121
|
+
}
|
|
122
|
+
textEllipsis(str, maxLength, { side = 'end', ellipsis = '...' } = {}) {
|
|
123
|
+
if (str.length > maxLength) {
|
|
124
|
+
switch (side) {
|
|
125
|
+
case 'start':
|
|
126
|
+
return ellipsis + str.slice(-(maxLength - ellipsis.length));
|
|
127
|
+
case 'end':
|
|
128
|
+
default:
|
|
129
|
+
return str.slice(0, maxLength - ellipsis.length) + ellipsis;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return str;
|
|
133
|
+
}
|
|
134
|
+
rankRecords(objectMap, compare, listSize) {
|
|
135
|
+
let rank = [];
|
|
136
|
+
for (const [, record] of Object.entries(objectMap)) {
|
|
137
|
+
if (record.n <= 1) {
|
|
138
|
+
continue; // only care about duplicated objects
|
|
139
|
+
}
|
|
140
|
+
let i = 0;
|
|
141
|
+
for (i = rank.length - 1; i >= 0; --i) {
|
|
142
|
+
const item = rank[i];
|
|
143
|
+
if (compare(item, record) >= 0) {
|
|
144
|
+
rank.splice(i + 1, 0, record);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (i < 0) {
|
|
149
|
+
rank.unshift(record);
|
|
150
|
+
}
|
|
151
|
+
rank = rank.slice(0, listSize);
|
|
152
|
+
}
|
|
153
|
+
return rank;
|
|
154
|
+
}
|
|
155
|
+
calculateTopDuplicatedObjectsInCount(objectMap) {
|
|
156
|
+
core_1.info.overwrite('calculating top duplicated objects in count...');
|
|
157
|
+
this.topDupObjInCnt = this.rankRecords(objectMap, (item1, item2) => item1.n - item2.n, this.topDupObjInCntListSize);
|
|
158
|
+
}
|
|
159
|
+
calculateTopDuplicatedObjectsInSize(objectMap) {
|
|
160
|
+
core_1.info.overwrite('calculating top duplicated objects in size...');
|
|
161
|
+
this.topDupObjInSize = this.rankRecords(objectMap, (item1, item2) => item1.size - item2.size, this.topDupObjInSizeListSize);
|
|
162
|
+
}
|
|
163
|
+
calculateobjectPatternsStatistics(objectMap) {
|
|
164
|
+
core_1.info.overwrite('calculating statistics for specified object patterns...');
|
|
165
|
+
const objectPatternStat = Object.create(null);
|
|
166
|
+
for (const [str, record] of Object.entries(objectMap)) {
|
|
167
|
+
patternLoop: for (const [patternName, patternCheck] of Object.entries(ObjectShallowAnalysis.objectPatternsToObserve)) {
|
|
168
|
+
if (!patternCheck(str)) {
|
|
169
|
+
continue patternLoop;
|
|
170
|
+
}
|
|
171
|
+
objectPatternStat[patternName] = objectPatternStat[patternName] || {
|
|
172
|
+
n: 0,
|
|
173
|
+
dupN: 0,
|
|
174
|
+
size: 0,
|
|
175
|
+
dupSize: 0,
|
|
176
|
+
};
|
|
177
|
+
const item = objectPatternStat[patternName];
|
|
178
|
+
item.n += record.n;
|
|
179
|
+
item.size += record.size;
|
|
180
|
+
if (record.n > 1) {
|
|
181
|
+
item.dupN += record.n - 1;
|
|
182
|
+
item.dupSize += (record.size * (record.n - 1)) / record.n;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
this.objectPatternsStat = objectPatternStat;
|
|
187
|
+
}
|
|
188
|
+
print() {
|
|
189
|
+
const sep = chalk_1.default.grey(', ');
|
|
190
|
+
const colon = chalk_1.default.grey(': ');
|
|
191
|
+
const beg = chalk_1.default.grey('[');
|
|
192
|
+
const end = chalk_1.default.grey(']');
|
|
193
|
+
const dot = chalk_1.default.grey('·');
|
|
194
|
+
const head = chalk_1.default.yellow.bind(chalk_1.default);
|
|
195
|
+
// print statistics of specified object patterns
|
|
196
|
+
for (const [str, item] of Object.entries(this.objectPatternsStat)) {
|
|
197
|
+
core_1.info.topLevel(head(`\n${str}`));
|
|
198
|
+
let p = core_1.utils.getReadablePercent(item.dupN / item.n);
|
|
199
|
+
core_1.info.topLevel(`${dot}Count: ${item.n} (${p} are duplicated)`);
|
|
200
|
+
const size = core_1.utils.getReadableBytes(item.size);
|
|
201
|
+
p = core_1.utils.getReadablePercent(item.dupSize / item.size);
|
|
202
|
+
core_1.info.topLevel(`${dot}Size: ${size} (${p} are duplicated)`);
|
|
203
|
+
}
|
|
204
|
+
core_1.info.topLevel(head('\nTop duplicated objects in count'));
|
|
205
|
+
let len = Math.min(15, this.topDupObjInCnt.length);
|
|
206
|
+
for (let i = 0; i < len; ++i) {
|
|
207
|
+
const item = this.topDupObjInCnt[i];
|
|
208
|
+
const size = core_1.utils.getReadableBytes(item.size);
|
|
209
|
+
const str = `"${chalk_1.default.blue(this.textEllipsis(item.obj, 100))}"`;
|
|
210
|
+
core_1.info.topLevel(` ${dot}${beg}${item.n}${sep}${size}${end}${colon}${str}`);
|
|
211
|
+
}
|
|
212
|
+
len = Math.min(15, this.topDupObjInSize.length);
|
|
213
|
+
core_1.info.topLevel(head('\nTop duplicated objects in size:'));
|
|
214
|
+
for (let i = 0; i < len; ++i) {
|
|
215
|
+
const item = this.topDupObjInSize[i];
|
|
216
|
+
const size = core_1.utils.getReadableBytes(item.size);
|
|
217
|
+
const str = `"${chalk_1.default.blue(this.textEllipsis(item.obj, 100))}"`;
|
|
218
|
+
const exampleIds = item.ids.slice(0, 10).map((id) => `@${id}`);
|
|
219
|
+
let examples = exampleIds.join(', ');
|
|
220
|
+
if (exampleIds.length < item.ids.length) {
|
|
221
|
+
examples += ' ...';
|
|
222
|
+
}
|
|
223
|
+
examples = chalk_1.default.grey(examples);
|
|
224
|
+
core_1.info.topLevel(`\n ${dot}${beg}${size}${sep}${item.n}${end}${colon}${str}`);
|
|
225
|
+
core_1.info.topLevel(` node examples: ${examples}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
ObjectShallowAnalysis.objectPatternsToObserve = {
|
|
230
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
231
|
+
'All objects': (_) => true,
|
|
232
|
+
};
|
|
233
|
+
exports.default = ObjectShallowAnalysis;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import type { HeapAnalysisOptions } from '../PluginUtils';
|
|
11
|
+
import { BaseOption } from '@memlab/core';
|
|
12
|
+
import BaseAnalysis from '../BaseAnalysis';
|
|
13
|
+
declare class ObjectShapeAnalysis extends BaseAnalysis {
|
|
14
|
+
getCommandName(): string;
|
|
15
|
+
getDescription(): string;
|
|
16
|
+
getOptions(): BaseOption[];
|
|
17
|
+
process(options: HeapAnalysisOptions): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export default ObjectShapeAnalysis;
|
|
20
|
+
//# sourceMappingURL=ObjectShapeAnalysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ObjectShapeAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/ObjectShapeAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAW,UAAU,EAAC,MAAM,cAAc,CAAC;AAClD,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAI3C,cAAM,mBAAoB,SAAQ,YAAY;IAC5C,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,UAAU,IAAI,UAAU,EAAE;IAIpB,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;CAI3D;AAED,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const core_1 = require("@memlab/core");
|
|
25
|
+
const BaseAnalysis_1 = __importDefault(require("../BaseAnalysis"));
|
|
26
|
+
const PluginUtils_1 = __importDefault(require("../PluginUtils"));
|
|
27
|
+
const HeapAnalysisSnapshotFileOption_1 = __importDefault(require("../options/HeapAnalysisSnapshotFileOption"));
|
|
28
|
+
class ObjectShapeAnalysis extends BaseAnalysis_1.default {
|
|
29
|
+
getCommandName() {
|
|
30
|
+
return 'shape';
|
|
31
|
+
}
|
|
32
|
+
getDescription() {
|
|
33
|
+
return 'List the shapes that retained most memory';
|
|
34
|
+
}
|
|
35
|
+
getOptions() {
|
|
36
|
+
return [new HeapAnalysisSnapshotFileOption_1.default()];
|
|
37
|
+
}
|
|
38
|
+
process(options) {
|
|
39
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
const snapshotPath = PluginUtils_1.default.getSnapshotFileForAnalysis(options);
|
|
41
|
+
yield core_1.analysis.breakDownMemoryByShapes({ file: snapshotPath });
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.default = ObjectShapeAnalysis;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import type { HeapAnalysisOptions } from '../PluginUtils';
|
|
11
|
+
import { BaseOption } from '@memlab/core';
|
|
12
|
+
import BaseAnalysis from '../BaseAnalysis';
|
|
13
|
+
declare class ObjectSizeRankAnalysis extends BaseAnalysis {
|
|
14
|
+
getCommandName(): string;
|
|
15
|
+
getDescription(): string;
|
|
16
|
+
getOptions(): BaseOption[];
|
|
17
|
+
process(options: HeapAnalysisOptions): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export default ObjectSizeRankAnalysis;
|
|
20
|
+
//# sourceMappingURL=ObjectSizeAnalysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ObjectSizeAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/ObjectSizeAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAI3C,cAAM,sBAAuB,SAAQ,YAAY;IAC/C,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,UAAU,IAAI,UAAU,EAAE;IAIpB,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ3D;AAED,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const BaseAnalysis_1 = __importDefault(require("../BaseAnalysis"));
|
|
25
|
+
const PluginUtils_1 = __importDefault(require("../PluginUtils"));
|
|
26
|
+
const HeapAnalysisSnapshotFileOption_1 = __importDefault(require("../options/HeapAnalysisSnapshotFileOption"));
|
|
27
|
+
class ObjectSizeRankAnalysis extends BaseAnalysis_1.default {
|
|
28
|
+
getCommandName() {
|
|
29
|
+
return 'object-size';
|
|
30
|
+
}
|
|
31
|
+
getDescription() {
|
|
32
|
+
return 'Get the largest objects in heap';
|
|
33
|
+
}
|
|
34
|
+
getOptions() {
|
|
35
|
+
return [new HeapAnalysisSnapshotFileOption_1.default()];
|
|
36
|
+
}
|
|
37
|
+
process(options) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const snapshot = yield PluginUtils_1.default.loadHeapSnapshot(options);
|
|
40
|
+
const largeObjects = PluginUtils_1.default.filterOutLargestObjects(snapshot, PluginUtils_1.default.isNodeWorthInspecting);
|
|
41
|
+
PluginUtils_1.default.printNodeListInTerminal(largeObjects);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.default = ObjectSizeRankAnalysis;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import type { HeapAnalysisOptions } from '../PluginUtils';
|
|
11
|
+
import { BaseOption } from '@memlab/core';
|
|
12
|
+
import BaseAnalysis from '../BaseAnalysis';
|
|
13
|
+
declare class ObjectUnboundGrowthAnalysis extends BaseAnalysis {
|
|
14
|
+
getCommandName(): string;
|
|
15
|
+
getDescription(): string;
|
|
16
|
+
getOptions(): BaseOption[];
|
|
17
|
+
process(options: HeapAnalysisOptions): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export default ObjectUnboundGrowthAnalysis;
|
|
20
|
+
//# sourceMappingURL=ObjectUnboundGrowthAnalysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ObjectUnboundGrowthAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/ObjectUnboundGrowthAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAmB,UAAU,EAAC,MAAM,cAAc,CAAC;AAC1D,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAI3C,cAAM,2BAA4B,SAAQ,YAAY;IACpD,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,UAAU,IAAI,UAAU,EAAE;IAIpB,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;CAM3D;AAED,eAAe,2BAA2B,CAAC"}
|