meminsight-core-publish 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.
Files changed (85) hide show
  1. package/dist/Index.d.ts +21 -0
  2. package/dist/Index.d.ts.map +1 -0
  3. package/dist/Index.js +65 -0
  4. package/dist/analyzer/AnalysisInfo.d.ts +112 -0
  5. package/dist/analyzer/AnalysisInfo.d.ts.map +1 -0
  6. package/dist/analyzer/AnalysisInfo.js +217 -0
  7. package/dist/analyzer/ArkAnalyzer.d.ts +30 -0
  8. package/dist/analyzer/ArkAnalyzer.d.ts.map +1 -0
  9. package/dist/analyzer/ArkAnalyzer.js +52 -0
  10. package/dist/analyzer/ArkCmpCfg.d.ts +15 -0
  11. package/dist/analyzer/ArkCmpCfg.d.ts.map +1 -0
  12. package/dist/analyzer/ArkCmpCfg.js +15 -0
  13. package/dist/analyzer/ArkCompareAnalyzer.d.ts +52 -0
  14. package/dist/analyzer/ArkCompareAnalyzer.d.ts.map +1 -0
  15. package/dist/analyzer/ArkCompareAnalyzer.js +144 -0
  16. package/dist/analyzer/ArkLeakAnalyzer.d.ts +14 -0
  17. package/dist/analyzer/ArkLeakAnalyzer.d.ts.map +1 -0
  18. package/dist/analyzer/ArkLeakAnalyzer.js +18 -0
  19. package/dist/analyzer/ArkSerializer.d.ts +18 -0
  20. package/dist/analyzer/ArkSerializer.d.ts.map +1 -0
  21. package/dist/analyzer/ArkSerializer.js +155 -0
  22. package/dist/analyzer/ArkStatAnalyzer.d.ts +56 -0
  23. package/dist/analyzer/ArkStatAnalyzer.d.ts.map +1 -0
  24. package/dist/analyzer/ArkStatAnalyzer.js +224 -0
  25. package/dist/analyzer/ArkStatCfg.d.ts +42 -0
  26. package/dist/analyzer/ArkStatCfg.d.ts.map +1 -0
  27. package/dist/analyzer/ArkStatCfg.js +42 -0
  28. package/dist/analyzer/ArkTracePath.d.ts +90 -0
  29. package/dist/analyzer/ArkTracePath.d.ts.map +1 -0
  30. package/dist/analyzer/ArkTracePath.js +245 -0
  31. package/dist/analyzer/ArkTracer.d.ts +17 -0
  32. package/dist/analyzer/ArkTracer.d.ts.map +1 -0
  33. package/dist/analyzer/ArkTracer.js +27 -0
  34. package/dist/analyzer/ArkXAnalyzer.d.ts +69 -0
  35. package/dist/analyzer/ArkXAnalyzer.d.ts.map +1 -0
  36. package/dist/analyzer/ArkXAnalyzer.js +616 -0
  37. package/dist/analyzer/IAnalyzer.d.ts +25 -0
  38. package/dist/analyzer/IAnalyzer.d.ts.map +1 -0
  39. package/dist/analyzer/IAnalyzer.js +2 -0
  40. package/dist/file/FileReader.d.ts +51 -0
  41. package/dist/file/FileReader.d.ts.map +1 -0
  42. package/dist/file/FileReader.js +110 -0
  43. package/dist/file/FileService.d.ts +23 -0
  44. package/dist/file/FileService.d.ts.map +1 -0
  45. package/dist/file/FileService.js +65 -0
  46. package/dist/file/FileWriter.d.ts +82 -0
  47. package/dist/file/FileWriter.d.ts.map +1 -0
  48. package/dist/file/FileWriter.js +160 -0
  49. package/dist/report/Reporter.d.ts +27 -0
  50. package/dist/report/Reporter.d.ts.map +1 -0
  51. package/dist/report/Reporter.js +61 -0
  52. package/dist/report/templates/template.d.ts +3 -0
  53. package/dist/report/templates/template.d.ts.map +1 -0
  54. package/dist/report/templates/template.js +106 -0
  55. package/dist/shell/DeviceShell.d.ts +96 -0
  56. package/dist/shell/DeviceShell.d.ts.map +1 -0
  57. package/dist/shell/DeviceShell.js +180 -0
  58. package/dist/shell/Shell.d.ts +52 -0
  59. package/dist/shell/Shell.d.ts.map +1 -0
  60. package/dist/shell/Shell.js +79 -0
  61. package/dist/types/Constants.d.ts +15 -0
  62. package/dist/types/Constants.d.ts.map +1 -0
  63. package/dist/types/Constants.js +18 -0
  64. package/dist/types/LeakTypes.d.ts +18 -0
  65. package/dist/types/LeakTypes.d.ts.map +1 -0
  66. package/dist/types/LeakTypes.js +2 -0
  67. package/dist/types/OhosTypes.d.ts +74 -0
  68. package/dist/types/OhosTypes.d.ts.map +1 -0
  69. package/dist/types/OhosTypes.js +83 -0
  70. package/dist/utils/Common.d.ts +14 -0
  71. package/dist/utils/Common.d.ts.map +1 -0
  72. package/dist/utils/Common.js +38 -0
  73. package/dist/utils/Finder.d.ts +163 -0
  74. package/dist/utils/Finder.d.ts.map +1 -0
  75. package/dist/utils/Finder.js +355 -0
  76. package/dist/utils/Loader.d.ts +30 -0
  77. package/dist/utils/Loader.d.ts.map +1 -0
  78. package/dist/utils/Loader.js +71 -0
  79. package/dist/utils/Log.d.ts +140 -0
  80. package/dist/utils/Log.d.ts.map +1 -0
  81. package/dist/utils/Log.js +177 -0
  82. package/dist/utils/Output.d.ts +126 -0
  83. package/dist/utils/Output.d.ts.map +1 -0
  84. package/dist/utils/Output.js +225 -0
  85. package/package.json +61 -0
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ArkCompareAnalyzer = void 0;
13
+ const core_1 = require("@memlab/core");
14
+ const ArkAnalyzer_1 = require("./ArkAnalyzer");
15
+ /**
16
+ * Ark Heapsnapshot 比较分析器
17
+ */
18
+ class ArkCompareAnalyzer extends ArkAnalyzer_1.ArkAnalyzer {
19
+ constructor() {
20
+ super();
21
+ this.DOMAIN = 'meminsight';
22
+ this.TAG = ArkCompareAnalyzer.name;
23
+ this.srcSnapshot = undefined;
24
+ this.dstSnapshot = undefined;
25
+ this.srcSnapshotFilePath = undefined;
26
+ this.dstSnapshotFilePath = undefined;
27
+ this.nodeName = undefined;
28
+ this.type = 'ark-compare-analyzer';
29
+ }
30
+ analyze(args) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ this.srcSnapshotFilePath = args[0];
33
+ this.dstSnapshotFilePath = args[1];
34
+ this.srcSnapshot = yield core_1.utils.getSnapshotFromFile(this.srcSnapshotFilePath, { buildNodeIdIndex: true });
35
+ this.dstSnapshot = yield core_1.utils.getSnapshotFromFile(this.dstSnapshotFilePath, { buildNodeIdIndex: true });
36
+ if (!this.srcSnapshot || !this.dstSnapshot) {
37
+ throw new Error("Failed to load heap snapshots");
38
+ }
39
+ return true;
40
+ });
41
+ }
42
+ getStatsOfAllNodes(snapshot) {
43
+ const stats = {};
44
+ snapshot.nodes.forEach((node) => {
45
+ const typeName = node.name;
46
+ if (!stats[typeName]) {
47
+ stats[typeName] = { count: 0, selfSize: 0, retainedSize: 0 };
48
+ }
49
+ stats[typeName].count += 1;
50
+ stats[typeName].selfSize += node.self_size;
51
+ stats[typeName].retainedSize += node.retainedSize;
52
+ });
53
+ return stats;
54
+ }
55
+ getStatsByNodeName(snapshot, name) {
56
+ const stats = {};
57
+ snapshot.nodes.forEach((node, _) => {
58
+ if (node.name === name) {
59
+ if (!stats[name]) {
60
+ stats[name] = { count: 0, selfSize: 0, retainedSize: 0 };
61
+ }
62
+ stats[name].count += 1;
63
+ stats[name].selfSize += node.self_size;
64
+ stats[name].retainedSize += node.retainedSize;
65
+ }
66
+ });
67
+ return stats;
68
+ }
69
+ getDetailStatsByNodeName(snapshot, nodeName) {
70
+ const stats = new Array();
71
+ snapshot.nodes.forEach((node, _) => {
72
+ if (node.name === nodeName) {
73
+ stats.push({ id: node.id, selfSize: node.self_size, retainedSize: node.retainedSize });
74
+ }
75
+ });
76
+ return stats;
77
+ }
78
+ getDiffs(record1, record2) {
79
+ const allTypes = new Set([
80
+ ...Object.keys(record1),
81
+ ...Object.keys(record2)
82
+ ]);
83
+ const diffs = [];
84
+ for (const typeName of allTypes) {
85
+ const srcStats = record1[typeName] || { count: 0, selfSize: 0, retainedSize: 0 };
86
+ const dstStats = record2[typeName] || { count: 0, selfSize: 0, retainedSize: 0 };
87
+ if (srcStats.count !== dstStats.count || srcStats.selfSize !== dstStats.selfSize || srcStats.retainedSize !== dstStats.retainedSize) {
88
+ diffs.push({
89
+ typeName,
90
+ srcCount: srcStats.count,
91
+ dstCount: dstStats.count,
92
+ countDiff: dstStats.count - srcStats.count,
93
+ srcSelfSize: srcStats.selfSize,
94
+ dstSelfSize: dstStats.selfSize,
95
+ selfSizeDiff: dstStats.selfSize - srcStats.selfSize,
96
+ srcRetainedSize: srcStats.retainedSize,
97
+ dstRetainedSize: dstStats.retainedSize,
98
+ retainedSizeDiff: dstStats.retainedSize - srcStats.retainedSize
99
+ });
100
+ }
101
+ }
102
+ return diffs;
103
+ }
104
+ diffSnapshots(node_name) {
105
+ let srcTypeStats = undefined;
106
+ let dstTypeStats = undefined;
107
+ if (node_name) {
108
+ // 按 node_name 统计源快照中的对象类型
109
+ srcTypeStats = this.getStatsByNodeName(this.srcSnapshot, node_name);
110
+ // 按 node_name 统计目标快照中的对象类型
111
+ dstTypeStats = this.getStatsByNodeName(this.dstSnapshot, node_name);
112
+ }
113
+ else {
114
+ // 统计源快照中的对象类型
115
+ srcTypeStats = this.getStatsOfAllNodes(this.srcSnapshot);
116
+ // 统计目标快照中的对象类型
117
+ dstTypeStats = this.getStatsOfAllNodes(this.dstSnapshot);
118
+ // console.log(`srcTypeStats: ${JSON.stringify(srcTypeStats)}`);
119
+ // console.log(`dstTypeStats: ${JSON.stringify(dstTypeStats)}`);
120
+ }
121
+ return this.getDiffs(srcTypeStats, dstTypeStats);
122
+ }
123
+ sortDiffs(type, diffs) {
124
+ return __awaiter(this, void 0, void 0, function* () {
125
+ let result = undefined;
126
+ if (type === 0) {
127
+ result = [...diffs].sort((a, b) => Math.abs(b.countDiff) - Math.abs(a.countDiff));
128
+ }
129
+ else if (type === 1) {
130
+ result = [...diffs].sort((a, b) => Math.abs(b.selfSizeDiff) - Math.abs(a.selfSizeDiff));
131
+ }
132
+ else if (type === 2) {
133
+ result = [...diffs].sort((a, b) => Math.abs(b.retainedSizeDiff) - Math.abs(a.retainedSizeDiff));
134
+ }
135
+ else {
136
+ result = [...diffs].sort((a, b) => Math.abs(b.countDiff) - Math.abs(a.countDiff));
137
+ }
138
+ return result;
139
+ });
140
+ }
141
+ }
142
+ exports.ArkCompareAnalyzer = ArkCompareAnalyzer;
143
+ ArkCompareAnalyzer.NAME = "ark-compare-analyzer";
144
+ ArkCompareAnalyzer.DESC = "Compare two heapsnapshot files and find the differences.";
@@ -0,0 +1,14 @@
1
+ import { IHeapSnapshot } from "@memlab/core";
2
+ import { ArkAnalyzer } from "./ArkAnalyzer";
3
+ /**
4
+ * Ark Heapsnapshot 内存泄漏分析器
5
+ */
6
+ export declare class ArkLeakAnalyzer extends ArkAnalyzer {
7
+ readonly DOMAIN = "meminsight";
8
+ readonly TAG: string;
9
+ static readonly NAME = "ark-leak-analyzer";
10
+ static readonly DESCRIPTION = "Analyze heapsnapshot files and find leaks.";
11
+ protected snapshotList: IHeapSnapshot[];
12
+ constructor();
13
+ }
14
+ //# sourceMappingURL=ArkLeakAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArkLeakAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/ArkLeakAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC5C,SAAgB,MAAM,gBAAgB;IACtC,SAAgB,GAAG,SAAwB;IAC3C,gBAAuB,IAAI,uBAAuB;IAClD,gBAAuB,WAAW,gDAAgD;IAElF,SAAS,CAAC,YAAY,EAAE,aAAa,EAAE,CAAC;;CAuL3C"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ArkLeakAnalyzer = void 0;
4
+ const ArkAnalyzer_1 = require("./ArkAnalyzer");
5
+ /**
6
+ * Ark Heapsnapshot 内存泄漏分析器
7
+ */
8
+ class ArkLeakAnalyzer extends ArkAnalyzer_1.ArkAnalyzer {
9
+ constructor() {
10
+ super();
11
+ this.DOMAIN = 'meminsight';
12
+ this.TAG = ArkLeakAnalyzer.name;
13
+ this.type = 'ark-leak-analyzer';
14
+ }
15
+ }
16
+ exports.ArkLeakAnalyzer = ArkLeakAnalyzer;
17
+ ArkLeakAnalyzer.NAME = 'ark-leak-analyzer';
18
+ ArkLeakAnalyzer.DESCRIPTION = "Analyze heapsnapshot files and find leaks.";
@@ -0,0 +1,18 @@
1
+ import { IHeapNode } from '@memlab/core';
2
+ import { ArkNodesMap, ArkTracePathItem } from './ArkTracePath';
3
+ import { ConsoleData, TextData, JsonData, HtmlData, OutputCfg } from '../utils/Output';
4
+ /**
5
+ * Ark Serializer
6
+ */
7
+ export declare class ArkSerializer {
8
+ private static getNodesTableTitle;
9
+ private static getNodesArrayData;
10
+ private static getNodesJsonArray;
11
+ static getTextDataByNodes(nodes: IHeapNode[], cfg?: OutputCfg): TextData | undefined;
12
+ static getJsonDataByNodes(nodes: IHeapNode[], cfg?: OutputCfg): JsonData;
13
+ static getConsoleDataByNodes(isTable: boolean, nodes: IHeapNode[], cfg?: OutputCfg): ConsoleData;
14
+ static getHtmlDataByNodes(nodes: IHeapNode[], cfg: OutputCfg): HtmlData;
15
+ static getNodeTracePathString(path: ArkTracePathItem | undefined): string;
16
+ static getArkNodesMapString(arkNodesMap: ArkNodesMap): string;
17
+ }
18
+ //# sourceMappingURL=ArkSerializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArkSerializer.d.ts","sourceRoot":"","sources":["../../src/analyzer/ArkSerializer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAc,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAoB,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEzG;;GAEG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAUjC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAuChC,OAAO,CAAC,MAAM,CAAC,iBAAiB;WA2BlB,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,GAAG,CAAC,EAAE,SAAS,GAAI,QAAQ,GAAG,SAAS;WA2B9E,kBAAkB,CAC5B,KAAK,EAAE,SAAS,EAAE,EAClB,GAAG,CAAC,EAAE,SAAS,GAChB,QAAQ;WAMG,qBAAqB,CAC/B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,SAAS,EAAE,EAClB,GAAG,CAAC,EAAE,SAAS,GAAI,WAAW;WAYpB,kBAAkB,CAC5B,KAAK,EAAE,SAAS,EAAE,EAClB,GAAG,EAAE,SAAS,GAAI,QAAQ;WAOhB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,SAAS,GAAI,MAAM;WAanE,oBAAoB,CAAC,WAAW,EAAE,WAAW,GAAI,MAAM;CAIxE"}
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ArkSerializer = void 0;
4
+ const core_1 = require("@memlab/core");
5
+ const Log_1 = require("../utils/Log");
6
+ const Output_1 = require("../utils/Output");
7
+ /**
8
+ * Ark Serializer
9
+ */
10
+ class ArkSerializer {
11
+ static getNodesTableTitle(cfg) {
12
+ var _a, _b, _c, _d, _e;
13
+ return [
14
+ ((_a = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _a === void 0 ? void 0 : _a.enableId) ? 'id' : '',
15
+ ((_b = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _b === void 0 ? void 0 : _b.enableType) ? 'type' : '',
16
+ ((_c = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _c === void 0 ? void 0 : _c.enableName) ? 'name' : '',
17
+ ((_d = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _d === void 0 ? void 0 : _d.enableSelfSize) ? 'self size' : '',
18
+ ((_e = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _e === void 0 ? void 0 : _e.enableRetainedSize) ? 'retained size' : ''
19
+ ].filter(item => !!item);
20
+ }
21
+ static getNodesArrayData(nodes, cfg) {
22
+ if (nodes.length === 0) {
23
+ return undefined;
24
+ }
25
+ let title = ArkSerializer.getNodesTableTitle(cfg);
26
+ let size = 0;
27
+ let body = nodes.reduce((acc, node) => {
28
+ var _a, _b, _c, _d, _e;
29
+ if ((_a = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _a === void 0 ? void 0 : _a.enableId) {
30
+ acc += `,${node.id}`;
31
+ size++;
32
+ }
33
+ if ((_b = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _b === void 0 ? void 0 : _b.enableType) {
34
+ acc += `,${node.type}`;
35
+ size++;
36
+ }
37
+ if ((_c = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _c === void 0 ? void 0 : _c.enableName) {
38
+ acc += `,${node.name}`;
39
+ size++;
40
+ }
41
+ if ((_d = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _d === void 0 ? void 0 : _d.enableSelfSize) {
42
+ acc += `,${node.self_size}`;
43
+ size++;
44
+ }
45
+ if ((_e = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _e === void 0 ? void 0 : _e.enableRetainedSize) {
46
+ acc += `,${node.retainedSize}`;
47
+ size++;
48
+ }
49
+ return acc;
50
+ }, '').split(',').filter(item => !!item);
51
+ let arr = title.concat(...body);
52
+ let data = arr.reduce((acc, _, i) => {
53
+ if (i % size === 0) {
54
+ acc.push(arr.slice(i, i + size));
55
+ }
56
+ return acc;
57
+ }, []);
58
+ return data;
59
+ }
60
+ static getNodesJsonArray(nodes, cfg) {
61
+ if (nodes.length === 0) {
62
+ return [];
63
+ }
64
+ const result = [];
65
+ nodes.forEach(node => {
66
+ var _a, _b, _c, _d, _e;
67
+ const jsonNode = {};
68
+ if ((_a = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _a === void 0 ? void 0 : _a.enableId) {
69
+ jsonNode["id"] = node.id;
70
+ }
71
+ if ((_b = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _b === void 0 ? void 0 : _b.enableType) {
72
+ jsonNode["type"] = node.type;
73
+ }
74
+ if ((_c = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _c === void 0 ? void 0 : _c.enableName) {
75
+ jsonNode["name"] = node.name;
76
+ }
77
+ if ((_d = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _d === void 0 ? void 0 : _d.enableSelfSize) {
78
+ jsonNode["selfSize"] = node.self_size;
79
+ }
80
+ if ((_e = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _e === void 0 ? void 0 : _e.enableRetainedSize) {
81
+ jsonNode["retainedSize"] = node.retainedSize;
82
+ }
83
+ result.push(jsonNode);
84
+ });
85
+ return result;
86
+ }
87
+ static getTextDataByNodes(nodes, cfg) {
88
+ if (nodes.length === 0) {
89
+ return undefined;
90
+ }
91
+ let desc = (cfg === null || cfg === void 0 ? void 0 : cfg.desc) || '';
92
+ let data = nodes.reduce((acc, node) => {
93
+ var _a, _b, _c, _d, _e;
94
+ if ((_a = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _a === void 0 ? void 0 : _a.enableName) {
95
+ acc += `[${node.name}]`;
96
+ }
97
+ if ((_b = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _b === void 0 ? void 0 : _b.enableType) {
98
+ acc += ` (${node.type})`;
99
+ }
100
+ if ((_c = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _c === void 0 ? void 0 : _c.enableId) {
101
+ acc += ` @${node.id}`;
102
+ }
103
+ if ((_d = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _d === void 0 ? void 0 : _d.enableSelfSize) {
104
+ acc += ` [${node.self_size}]`;
105
+ }
106
+ if ((_e = cfg === null || cfg === void 0 ? void 0 : cfg.node) === null || _e === void 0 ? void 0 : _e.enableRetainedSize) {
107
+ acc += ` [${node.retainedSize}]`;
108
+ }
109
+ acc += '\n';
110
+ return acc;
111
+ }, '');
112
+ return new Output_1.TextData(desc, data);
113
+ }
114
+ static getJsonDataByNodes(nodes, cfg) {
115
+ let jsonArr = ArkSerializer.getNodesJsonArray(nodes, cfg);
116
+ let desc = (cfg === null || cfg === void 0 ? void 0 : cfg.desc) || {};
117
+ return new Output_1.JsonData(desc, jsonArr);
118
+ }
119
+ static getConsoleDataByNodes(isTable, nodes, cfg) {
120
+ if (isTable) {
121
+ let titleArr = ArkSerializer.getNodesTableTitle(cfg);
122
+ let jsonArr = ArkSerializer.getNodesJsonArray(nodes, cfg);
123
+ const tabalData = new Output_1.ConsoleTableData(titleArr, jsonArr);
124
+ return new Output_1.ConsoleData(isTable, tabalData);
125
+ }
126
+ else {
127
+ let textData = ArkSerializer.getTextDataByNodes(nodes, cfg);
128
+ return new Output_1.ConsoleData(isTable, textData === null || textData === void 0 ? void 0 : textData.data);
129
+ }
130
+ }
131
+ static getHtmlDataByNodes(nodes, cfg) {
132
+ // TODO
133
+ let jsonArr = ArkSerializer.getNodesJsonArray(nodes, cfg);
134
+ let desc = (cfg === null || cfg === void 0 ? void 0 : cfg.desc) || '';
135
+ return new Output_1.HtmlData(desc, jsonArr);
136
+ }
137
+ static getNodeTracePathString(path) {
138
+ var _a;
139
+ if (!path) {
140
+ Log_1.Log.error('meminsight', ArkSerializer.name, 'trace path not found.');
141
+ return '';
142
+ }
143
+ let snapshot = (_a = path.node) === null || _a === void 0 ? void 0 : _a.snapshot;
144
+ if (!snapshot) {
145
+ Log_1.Log.error('meminsight', ArkSerializer.name, 'snapshot not found.');
146
+ return '';
147
+ }
148
+ return core_1.serializer.summarizePath(path, new Set(), snapshot);
149
+ }
150
+ static getArkNodesMapString(arkNodesMap) {
151
+ // TODO:
152
+ return '';
153
+ }
154
+ }
155
+ exports.ArkSerializer = ArkSerializer;
@@ -0,0 +1,56 @@
1
+ import { IHeapSnapshot, IHeapNode } from "@memlab/core";
2
+ import { ArkAnalyzer } from "./ArkAnalyzer";
3
+ import { ILoggable } from "../utils/Log";
4
+ import { ArkNodesMap, ArkTracePathItem } from './ArkTracePath';
5
+ /**
6
+ * Ark Heapsnapshot 统计分析器
7
+ */
8
+ export declare class ArkStatAnalyzer extends ArkAnalyzer implements ILoggable {
9
+ readonly DOMAIN = "meminsight";
10
+ readonly TAG: string;
11
+ static readonly NAME = "ark-stat-analyzer";
12
+ static readonly DESC = "Analyze single heapsnapshot file and show statistics.";
13
+ protected snapshot: IHeapSnapshot;
14
+ protected snapshotFilePath: string;
15
+ constructor();
16
+ analyze(args: any[]): Promise<any>;
17
+ /**
18
+ * get snapshot file path
19
+ * @returns snapshot file path
20
+ */
21
+ getSnapshotFilePath(): string;
22
+ getGCRoots(): Promise<Array<IHeapNode>>;
23
+ getDetachedNodes(): Promise<Array<IHeapNode>>;
24
+ getNodesByFilterCondition(filter: (condition: any) => boolean, condition: any): Promise<Array<IHeapNode>>;
25
+ getNodesByConfig(): Promise<Array<IHeapNode>>;
26
+ /**
27
+ * 获取指定节点的最短引用路径
28
+ * @param nodeId node id
29
+ * @returns 最短引用路径
30
+ */
31
+ getShortestPathToNode(nodeId: number): Promise<ArkTracePathItem | undefined>;
32
+ /**
33
+ * 根据配置参数获取符合条件的节点信息
34
+ * @param nameWhiteList class name 白名单
35
+ * @param typeWhiteList node type 白名单
36
+ * @param enableShortestPath 是否生成最短路径
37
+ * @param enableAggrationPath 是否生成聚合路径,enableShortestPath 为 true 时有效
38
+ * @param maxAggrationLength 最大聚合路径的个数,enableShortestPath 为 true 时有效
39
+ * @param enableMinRetainedSize 是否按最小retained size过滤,enableShortestPath 为 true 时有效
40
+ * @param minRetainedSize 最小retained size,enableShortestPath 为 true 时有效
41
+ * @param descending 聚合路径是否自上而下排序,enableShortestPath 为 true 时有效
42
+ * @returns 节点路径信息,可以按节点名、节点类型、节点到GC Roots的最短路径等信息过滤
43
+ */
44
+ getArkNodesMap(nameWhiteList: string[], typeWhiteList?: string[], enableShortestPath?: boolean, enableAggrationPath?: boolean, maxAggrationLength?: number, enableMinRetainedSize?: boolean, minRetainedSize?: number, descending?: boolean): Promise<ArkNodesMap | undefined>;
45
+ /**
46
+ * 根据配置获取符合条件的节点信息
47
+ * 配置通过 setConfig(cfg: any) 设置,默认配置参见 ArkStatCfg.defaultArkStatCfg()
48
+ */
49
+ getArkNodesMapByConfig(): Promise<ArkNodesMap | undefined>;
50
+ /**
51
+ * 获取所有共享对象,Map 以对象tag作为 key,相同tag的对象作为 value
52
+ * @returns Map<string, Array<IHeapNode>>
53
+ */
54
+ getSharedHeapNodesMap(): Promise<Map<string, Array<IHeapNode>>>;
55
+ }
56
+ //# sourceMappingURL=ArkStatAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArkStatAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/ArkStatAnalyzer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAqB,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAO,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE/D;;GAEG;AACH,qBAAa,eAAgB,SAAQ,WAAY,YAAW,SAAS;IACjE,SAAgB,MAAM,gBAAgB;IACtC,SAAgB,GAAG,SAAwB;IAC3C,gBAAuB,IAAI,uBAAuB;IAClD,gBAAuB,IAAI,2DAA2D;IAEtF,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC;IAClC,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAC;;IAOb,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,GAAI,OAAO,CAAC,GAAG,CAAC;IAczD;;;OAGG;IACI,mBAAmB,IAAK,MAAM;IAIxB,UAAU,IAAK,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAQxC,gBAAgB,IAAK,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAQ9C,yBAAyB,CAClC,MAAM,EAAE,CAAC,SAAS,EAAE,GAAG,KAAK,OAAO,EACnC,SAAS,EAAE,GAAG,GAAI,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAclC,gBAAgB,IAAK,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAsB3D;;;;OAIG;IACU,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAI,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAa1F;;;;;;;;;;;OAWG;IACU,cAAc,CACvB,aAAa,EAAE,MAAM,EAAE,EACvB,aAAa,GAAE,MAAM,EAAe,EACpC,kBAAkB,GAAE,OAAc,EAClC,mBAAmB,GAAE,OAAc,EACnC,kBAAkB,SAAI,EACtB,qBAAqB,UAAQ,EAC7B,eAAe,SAAc,EAC7B,UAAU,GAAE,OAAc,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAoBjE;;;OAGG;IACU,sBAAsB,IAAK,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAmBvE;;;MAGE;IACU,qBAAqB,IAAK,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;CAGhF"}
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.ArkStatAnalyzer = void 0;
46
+ const fs = __importStar(require("fs"));
47
+ const ArkAnalyzer_1 = require("./ArkAnalyzer");
48
+ const Loader_1 = require("../utils/Loader");
49
+ const Finder_1 = require("../utils/Finder");
50
+ const Log_1 = require("../utils/Log");
51
+ const ArkTracePath_1 = require("./ArkTracePath");
52
+ /**
53
+ * Ark Heapsnapshot 统计分析器
54
+ */
55
+ class ArkStatAnalyzer extends ArkAnalyzer_1.ArkAnalyzer {
56
+ constructor() {
57
+ super();
58
+ this.DOMAIN = 'meminsight';
59
+ this.TAG = ArkStatAnalyzer.name;
60
+ this.type = 'ark-stat-analyzer';
61
+ }
62
+ analyze(args) {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ if (args.length < 1) {
65
+ Log_1.Log.errorX(this, 'Argument count is not enough.');
66
+ return undefined;
67
+ }
68
+ this.snapshotFilePath = args[0];
69
+ if (!fs.existsSync(this.snapshotFilePath)) {
70
+ Log_1.Log.errorX(this, `File not found, ${this.snapshotFilePath}`);
71
+ return undefined;
72
+ }
73
+ this.snapshot = yield Loader_1.Loader.loadFromFile(this.snapshotFilePath);
74
+ return this.snapshot;
75
+ });
76
+ }
77
+ /**
78
+ * get snapshot file path
79
+ * @returns snapshot file path
80
+ */
81
+ getSnapshotFilePath() {
82
+ return this.snapshotFilePath;
83
+ }
84
+ getGCRoots() {
85
+ return __awaiter(this, void 0, void 0, function* () {
86
+ if (!this.snapshot) {
87
+ Log_1.Log.errorX(this, 'Heapsnapshot has not been loaded.');
88
+ return [];
89
+ }
90
+ return Finder_1.Finder.findGCRoots(this.snapshot);
91
+ });
92
+ }
93
+ getDetachedNodes() {
94
+ return __awaiter(this, void 0, void 0, function* () {
95
+ if (!this.snapshot) {
96
+ Log_1.Log.errorX(this, 'Heapsnapshot has not been loaded.');
97
+ return [];
98
+ }
99
+ return Finder_1.Finder.findDetachedNodes(this.snapshot);
100
+ });
101
+ }
102
+ getNodesByFilterCondition(filter, condition) {
103
+ return __awaiter(this, void 0, void 0, function* () {
104
+ if (!this.snapshot) {
105
+ Log_1.Log.errorX(this, 'Heapsnapshot has not been loaded.');
106
+ return [];
107
+ }
108
+ const result = new Array();
109
+ this.snapshot.nodes.forEach((node) => {
110
+ if (filter(condition)) {
111
+ result.push(node);
112
+ }
113
+ });
114
+ return result;
115
+ });
116
+ }
117
+ getNodesByConfig() {
118
+ return __awaiter(this, void 0, void 0, function* () {
119
+ if (!this.snapshot) {
120
+ Log_1.Log.errorX(this, 'Heapsnapshot has not been loaded.');
121
+ return [];
122
+ }
123
+ const result = new Array();
124
+ let cfg = this.configuration;
125
+ if (cfg) {
126
+ this.snapshot.nodes.forEach((node) => {
127
+ if (!((cfg.Node.enableTypeWhiteList && !cfg.Node.typeWhiteList.includes(node.type))
128
+ || (cfg.Node.enableTypeBlackList && cfg.Node.typeBlackList.includes(node.type))
129
+ || (cfg.Node.enableNameWhiteList && !cfg.Node.nameWhiteList.includes(node.name))
130
+ || (cfg.Node.enableNameBlackList && cfg.Node.nameBlackList.includes(node.name)))) {
131
+ result.push(node);
132
+ }
133
+ });
134
+ }
135
+ else {
136
+ Log_1.Log.errorX(this, 'No analyzer configuration found.');
137
+ }
138
+ return result;
139
+ });
140
+ }
141
+ /**
142
+ * 获取指定节点的最短引用路径
143
+ * @param nodeId node id
144
+ * @returns 最短引用路径
145
+ */
146
+ getShortestPathToNode(nodeId) {
147
+ return __awaiter(this, void 0, void 0, function* () {
148
+ if (!this.snapshot) {
149
+ Log_1.Log.errorX(this, 'Heapsnapshot has not been loaded.');
150
+ return undefined;
151
+ }
152
+ const node = this.snapshot.nodes.get(nodeId);
153
+ if (!node) {
154
+ Log_1.Log.errorX(this, `Node(${nodeId}) does not exist.`);
155
+ return undefined;
156
+ }
157
+ return Finder_1.Finder.findShortestPathToGCRoot(this.snapshot, node);
158
+ });
159
+ }
160
+ /**
161
+ * 根据配置参数获取符合条件的节点信息
162
+ * @param nameWhiteList class name 白名单
163
+ * @param typeWhiteList node type 白名单
164
+ * @param enableShortestPath 是否生成最短路径
165
+ * @param enableAggrationPath 是否生成聚合路径,enableShortestPath 为 true 时有效
166
+ * @param maxAggrationLength 最大聚合路径的个数,enableShortestPath 为 true 时有效
167
+ * @param enableMinRetainedSize 是否按最小retained size过滤,enableShortestPath 为 true 时有效
168
+ * @param minRetainedSize 最小retained size,enableShortestPath 为 true 时有效
169
+ * @param descending 聚合路径是否自上而下排序,enableShortestPath 为 true 时有效
170
+ * @returns 节点路径信息,可以按节点名、节点类型、节点到GC Roots的最短路径等信息过滤
171
+ */
172
+ getArkNodesMap(nameWhiteList_1) {
173
+ return __awaiter(this, arguments, void 0, function* (nameWhiteList, typeWhiteList = ['object'], enableShortestPath = true, enableAggrationPath = true, maxAggrationLength = 3, enableMinRetainedSize = false, minRetainedSize = 1024 * 1024, descending = true) {
174
+ if (!this.snapshot) {
175
+ Log_1.Log.errorX(this, 'Heapsnapshot has not been loaded.');
176
+ return undefined;
177
+ }
178
+ const result = new ArkTracePath_1.ArkNodesMap();
179
+ this.snapshot.nodes.forEach((node) => {
180
+ result.addNode(this.snapshot, node, nameWhiteList, typeWhiteList, enableShortestPath);
181
+ });
182
+ if (enableShortestPath && enableAggrationPath) {
183
+ for (const [key, value] of result) {
184
+ value.getAggrationPathIndexes(descending, maxAggrationLength, enableMinRetainedSize ? minRetainedSize : -1);
185
+ }
186
+ }
187
+ return result;
188
+ });
189
+ }
190
+ /**
191
+ * 根据配置获取符合条件的节点信息
192
+ * 配置通过 setConfig(cfg: any) 设置,默认配置参见 ArkStatCfg.defaultArkStatCfg()
193
+ */
194
+ getArkNodesMapByConfig() {
195
+ return __awaiter(this, void 0, void 0, function* () {
196
+ let cfg = this.configuration;
197
+ if (!cfg) {
198
+ Log_1.Log.errorX(this, 'No analyzer configuration found.');
199
+ return undefined;
200
+ }
201
+ let nameWhiteList = cfg.Node.nameWhiteList;
202
+ let typeWhiteList = cfg.Node.typeWhiteList;
203
+ let enableShortestPath = cfg.Path.enableShortest;
204
+ let enableAggrationPath = cfg.Path.enableAggration;
205
+ let maxAggrationLength = cfg.Path.aggrationLength;
206
+ let enableMinRetainedSize = cfg.Path.enableMinRetainedSize;
207
+ let minRetainedSize = cfg.Path.minRetainedSize;
208
+ let descending = cfg.Path.aggrationDescending;
209
+ return this.getArkNodesMap(nameWhiteList, typeWhiteList, enableShortestPath, enableAggrationPath, maxAggrationLength, enableMinRetainedSize, minRetainedSize, descending);
210
+ });
211
+ }
212
+ /**
213
+ * 获取所有共享对象,Map 以对象tag作为 key,相同tag的对象作为 value
214
+ * @returns Map<string, Array<IHeapNode>>
215
+ */
216
+ getSharedHeapNodesMap() {
217
+ return __awaiter(this, void 0, void 0, function* () {
218
+ return Finder_1.Finder.getSharedHeapNodesMap(this.snapshot);
219
+ });
220
+ }
221
+ }
222
+ exports.ArkStatAnalyzer = ArkStatAnalyzer;
223
+ ArkStatAnalyzer.NAME = 'ark-stat-analyzer';
224
+ ArkStatAnalyzer.DESC = "Analyze single heapsnapshot file and show statistics.";