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.
- package/dist/Index.d.ts +21 -0
- package/dist/Index.d.ts.map +1 -0
- package/dist/Index.js +65 -0
- package/dist/analyzer/AnalysisInfo.d.ts +112 -0
- package/dist/analyzer/AnalysisInfo.d.ts.map +1 -0
- package/dist/analyzer/AnalysisInfo.js +217 -0
- package/dist/analyzer/ArkAnalyzer.d.ts +30 -0
- package/dist/analyzer/ArkAnalyzer.d.ts.map +1 -0
- package/dist/analyzer/ArkAnalyzer.js +52 -0
- package/dist/analyzer/ArkCmpCfg.d.ts +15 -0
- package/dist/analyzer/ArkCmpCfg.d.ts.map +1 -0
- package/dist/analyzer/ArkCmpCfg.js +15 -0
- package/dist/analyzer/ArkCompareAnalyzer.d.ts +52 -0
- package/dist/analyzer/ArkCompareAnalyzer.d.ts.map +1 -0
- package/dist/analyzer/ArkCompareAnalyzer.js +144 -0
- package/dist/analyzer/ArkLeakAnalyzer.d.ts +14 -0
- package/dist/analyzer/ArkLeakAnalyzer.d.ts.map +1 -0
- package/dist/analyzer/ArkLeakAnalyzer.js +18 -0
- package/dist/analyzer/ArkSerializer.d.ts +18 -0
- package/dist/analyzer/ArkSerializer.d.ts.map +1 -0
- package/dist/analyzer/ArkSerializer.js +155 -0
- package/dist/analyzer/ArkStatAnalyzer.d.ts +56 -0
- package/dist/analyzer/ArkStatAnalyzer.d.ts.map +1 -0
- package/dist/analyzer/ArkStatAnalyzer.js +224 -0
- package/dist/analyzer/ArkStatCfg.d.ts +42 -0
- package/dist/analyzer/ArkStatCfg.d.ts.map +1 -0
- package/dist/analyzer/ArkStatCfg.js +42 -0
- package/dist/analyzer/ArkTracePath.d.ts +90 -0
- package/dist/analyzer/ArkTracePath.d.ts.map +1 -0
- package/dist/analyzer/ArkTracePath.js +245 -0
- package/dist/analyzer/ArkTracer.d.ts +17 -0
- package/dist/analyzer/ArkTracer.d.ts.map +1 -0
- package/dist/analyzer/ArkTracer.js +27 -0
- package/dist/analyzer/ArkXAnalyzer.d.ts +69 -0
- package/dist/analyzer/ArkXAnalyzer.d.ts.map +1 -0
- package/dist/analyzer/ArkXAnalyzer.js +616 -0
- package/dist/analyzer/IAnalyzer.d.ts +25 -0
- package/dist/analyzer/IAnalyzer.d.ts.map +1 -0
- package/dist/analyzer/IAnalyzer.js +2 -0
- package/dist/file/FileReader.d.ts +51 -0
- package/dist/file/FileReader.d.ts.map +1 -0
- package/dist/file/FileReader.js +110 -0
- package/dist/file/FileService.d.ts +23 -0
- package/dist/file/FileService.d.ts.map +1 -0
- package/dist/file/FileService.js +65 -0
- package/dist/file/FileWriter.d.ts +82 -0
- package/dist/file/FileWriter.d.ts.map +1 -0
- package/dist/file/FileWriter.js +160 -0
- package/dist/report/Reporter.d.ts +27 -0
- package/dist/report/Reporter.d.ts.map +1 -0
- package/dist/report/Reporter.js +61 -0
- package/dist/report/templates/template.d.ts +3 -0
- package/dist/report/templates/template.d.ts.map +1 -0
- package/dist/report/templates/template.js +106 -0
- package/dist/shell/DeviceShell.d.ts +96 -0
- package/dist/shell/DeviceShell.d.ts.map +1 -0
- package/dist/shell/DeviceShell.js +180 -0
- package/dist/shell/Shell.d.ts +52 -0
- package/dist/shell/Shell.d.ts.map +1 -0
- package/dist/shell/Shell.js +79 -0
- package/dist/types/Constants.d.ts +15 -0
- package/dist/types/Constants.d.ts.map +1 -0
- package/dist/types/Constants.js +18 -0
- package/dist/types/LeakTypes.d.ts +18 -0
- package/dist/types/LeakTypes.d.ts.map +1 -0
- package/dist/types/LeakTypes.js +2 -0
- package/dist/types/OhosTypes.d.ts +74 -0
- package/dist/types/OhosTypes.d.ts.map +1 -0
- package/dist/types/OhosTypes.js +83 -0
- package/dist/utils/Common.d.ts +14 -0
- package/dist/utils/Common.d.ts.map +1 -0
- package/dist/utils/Common.js +38 -0
- package/dist/utils/Finder.d.ts +163 -0
- package/dist/utils/Finder.d.ts.map +1 -0
- package/dist/utils/Finder.js +355 -0
- package/dist/utils/Loader.d.ts +30 -0
- package/dist/utils/Loader.d.ts.map +1 -0
- package/dist/utils/Loader.js +71 -0
- package/dist/utils/Log.d.ts +140 -0
- package/dist/utils/Log.d.ts.map +1 -0
- package/dist/utils/Log.js +177 -0
- package/dist/utils/Output.d.ts +126 -0
- package/dist/utils/Output.d.ts.map +1 -0
- package/dist/utils/Output.js +225 -0
- package/package.json +61 -0
|
@@ -0,0 +1,616 @@
|
|
|
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.ArkXAnalyzer = exports.ArkXSortType = void 0;
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const heap_analysis_1 = require("@memlab/heap-analysis");
|
|
49
|
+
const ArkAnalyzer_1 = require("./ArkAnalyzer");
|
|
50
|
+
const Finder_1 = require("../utils/Finder");
|
|
51
|
+
const Log_1 = require("../utils/Log");
|
|
52
|
+
const AnalysisInfo_1 = require("./AnalysisInfo");
|
|
53
|
+
const Reporter_1 = require("../report/Reporter");
|
|
54
|
+
var ArkXSortType;
|
|
55
|
+
(function (ArkXSortType) {
|
|
56
|
+
ArkXSortType[ArkXSortType["BY_RETAINED_SIZE"] = 0] = "BY_RETAINED_SIZE";
|
|
57
|
+
ArkXSortType[ArkXSortType["BY_COUNT"] = 1] = "BY_COUNT";
|
|
58
|
+
})(ArkXSortType || (exports.ArkXSortType = ArkXSortType = {}));
|
|
59
|
+
/**
|
|
60
|
+
* Ark Heapsnapshot 统计分析器
|
|
61
|
+
*/
|
|
62
|
+
class ArkXAnalyzer extends ArkAnalyzer_1.ArkAnalyzer {
|
|
63
|
+
constructor() {
|
|
64
|
+
super();
|
|
65
|
+
this.DOMAIN = 'meminsight';
|
|
66
|
+
this.TAG = ArkXAnalyzer.name;
|
|
67
|
+
this.type = 'ark-x-analyzer';
|
|
68
|
+
this.config = {
|
|
69
|
+
topN: 10,
|
|
70
|
+
sortType: ArkXSortType.BY_RETAINED_SIZE,
|
|
71
|
+
tags: []
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
setConfig(config) {
|
|
75
|
+
this.config = config;
|
|
76
|
+
}
|
|
77
|
+
analyze(args) {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
let file = args[0];
|
|
80
|
+
let list = args[1];
|
|
81
|
+
let topN = args[2];
|
|
82
|
+
let sortType = args[3];
|
|
83
|
+
let tags = args[4];
|
|
84
|
+
// 处理文件路径
|
|
85
|
+
this.snapshotFiles = [];
|
|
86
|
+
if (file !== undefined && file !== '') {
|
|
87
|
+
this.snapshotFiles.push(path.resolve(file));
|
|
88
|
+
}
|
|
89
|
+
if (list !== undefined && list.length > 0) {
|
|
90
|
+
list.forEach(item => {
|
|
91
|
+
let itemPath = path.resolve(item);
|
|
92
|
+
if (this.snapshotFiles.indexOf(itemPath) === -1) {
|
|
93
|
+
this.snapshotFiles.push(itemPath);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
console.info(`Heapsnapshot Files:`);
|
|
98
|
+
this.snapshotFiles.forEach(item => {
|
|
99
|
+
console.info(item);
|
|
100
|
+
});
|
|
101
|
+
// 设置 config
|
|
102
|
+
this.config.topN = topN <= 0 ? 10 : topN;
|
|
103
|
+
this.config.sortType = sortType == 0 ? ArkXSortType.BY_RETAINED_SIZE : ArkXSortType.BY_COUNT;
|
|
104
|
+
console.log(`TopN: ${topN}\nSortType: ${this.config.sortType.toString()}`);
|
|
105
|
+
if (tags != undefined && tags.length > 0) {
|
|
106
|
+
this.config.tags = tags;
|
|
107
|
+
console.info(`Tags:`);
|
|
108
|
+
tags.forEach(tag => {
|
|
109
|
+
console.info(tag);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
for (let i = 0; i < this.snapshotFiles.length; i++) {
|
|
113
|
+
let filepath = this.snapshotFiles.at(i);
|
|
114
|
+
if (!fs.existsSync(filepath)) {
|
|
115
|
+
Log_1.Log.errorX(this, `File not found, ${filepath}`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
let infos = yield this.analyzeOne(filepath);
|
|
119
|
+
let datas = [];
|
|
120
|
+
infos.forEach((info) => {
|
|
121
|
+
let data = info.toReportData();
|
|
122
|
+
datas.push(data);
|
|
123
|
+
});
|
|
124
|
+
Reporter_1.ReporterHTML.generateByTemplate(datas, path.basename(filepath));
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
analyzeOne(filepath) {
|
|
129
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
let snapshot;
|
|
131
|
+
const results = [];
|
|
132
|
+
try {
|
|
133
|
+
console.info("Start to parse heapsnapshot: ", filepath);
|
|
134
|
+
snapshot = yield (0, heap_analysis_1.getFullHeapFromFile)(filepath);
|
|
135
|
+
if (snapshot === undefined) {
|
|
136
|
+
console.info(`Failed to parse heapsnapshot: ${filepath}, snapshot is undefined.`);
|
|
137
|
+
return results;
|
|
138
|
+
}
|
|
139
|
+
console.info('Success to parse heapsnapshot: ', filepath);
|
|
140
|
+
let result;
|
|
141
|
+
let TopN = this.config.topN;
|
|
142
|
+
// 同类名的基础对象统计&聚合 (如 JSObject, global_env...)
|
|
143
|
+
const baseObjectWithSameNameList = [
|
|
144
|
+
'JSObject', 'js_shared_object',
|
|
145
|
+
'js_array', 'js_map', 'js_set',
|
|
146
|
+
'js_proxy', 'js_native_pointer', 'js_weak_ref'
|
|
147
|
+
];
|
|
148
|
+
baseObjectWithSameNameList.forEach(objectName => {
|
|
149
|
+
result = this.statSpecificObjectNameByDistance(snapshot, objectName);
|
|
150
|
+
results.push(result);
|
|
151
|
+
result = this.aggregateSpecificObjectNameByReference(snapshot, objectName, TopN);
|
|
152
|
+
results.push(result);
|
|
153
|
+
result = this.aggregateSpecificObjectNameByDistance1(snapshot, objectName, TopN);
|
|
154
|
+
results.push(result);
|
|
155
|
+
});
|
|
156
|
+
// 同类型的基础对象统计&聚合
|
|
157
|
+
const baseObjectWithSameTypeList = ['string', 'system', 'framework', 'array'];
|
|
158
|
+
baseObjectWithSameTypeList.forEach(objectType => {
|
|
159
|
+
result = this.aggregateSpecificObjectInfoByClassName(snapshot, objectType, [], TopN);
|
|
160
|
+
results.push(result);
|
|
161
|
+
result = this.aggregateSpecificObjectInfoByReference(snapshot, '', objectType, [], TopN);
|
|
162
|
+
results.push(result);
|
|
163
|
+
});
|
|
164
|
+
// 业务对象统计&聚合
|
|
165
|
+
const tags = this.config.tags;
|
|
166
|
+
if (tags.length > 0) {
|
|
167
|
+
result = this.aggregateSpecificObjectInfoByClassName(snapshot, '', tags, TopN);
|
|
168
|
+
results.push(result);
|
|
169
|
+
result = this.aggregateSpecificObjectInfoByReference(snapshot, '', '', tags, TopN);
|
|
170
|
+
results.push(result);
|
|
171
|
+
}
|
|
172
|
+
return results;
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
console.error('Failed to parse heapsnapshot, ', error);
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
// TODO:
|
|
179
|
+
}
|
|
180
|
+
return [];
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 指定类名对象按 Distance 统计
|
|
185
|
+
*/
|
|
186
|
+
statSpecificObjectNameByDistance(snapshot, objectName) {
|
|
187
|
+
console.log(`\n\n========================${objectName} 对象按 Distance 统计=========================\n`);
|
|
188
|
+
let totalHeapSize = 0;
|
|
189
|
+
let totalRetainSize = 0;
|
|
190
|
+
let totalSelfSize = 0;
|
|
191
|
+
let totalCount = 0;
|
|
192
|
+
let countMap = new Map();
|
|
193
|
+
let retainSizeMap = new Map();
|
|
194
|
+
let selfSizeMap = new Map();
|
|
195
|
+
snapshot.nodes.forEach((node) => {
|
|
196
|
+
totalHeapSize += node.self_size;
|
|
197
|
+
if (node.name === objectName) {
|
|
198
|
+
totalCount++;
|
|
199
|
+
totalRetainSize += node.retainedSize;
|
|
200
|
+
totalSelfSize += node.self_size;
|
|
201
|
+
let distance = Finder_1.Finder.getShortestPath(node)[2];
|
|
202
|
+
countMap.set(distance, (countMap.get(distance) || 0) + 1);
|
|
203
|
+
selfSizeMap.set(distance, (selfSizeMap.get(distance) || 0) + node.self_size);
|
|
204
|
+
retainSizeMap.set(distance, (retainSizeMap.get(distance) || 0) + node.retainedSize);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
console.log(`Total Heap Size: ${(totalHeapSize / 1024 / 1024).toFixed(2)} MB`);
|
|
208
|
+
console.log(`Total ${objectName} Self Size: ${(totalSelfSize / 1024).toFixed(2)} KB, Ratio: ${(totalSelfSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
209
|
+
console.log(`Total ${objectName} Retained Size: ${(totalRetainSize / 1024).toFixed(2)} KB, Ratio: ${(totalRetainSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
210
|
+
console.log(`Total ${objectName} Count: ${totalCount}`);
|
|
211
|
+
// 按距离统计取全部数据
|
|
212
|
+
let sortedeMap;
|
|
213
|
+
if (this.config.sortType === ArkXSortType.BY_COUNT) {
|
|
214
|
+
console.log(`\n${objectName} Info By Count:`);
|
|
215
|
+
sortedeMap = new Map([...countMap].sort((a, b) => b[1] - a[1]));
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
console.log(`\n${objectName} Info By Retained Size:`);
|
|
219
|
+
sortedeMap = new Map([...retainSizeMap].sort((a, b) => b[1] - a[1]));
|
|
220
|
+
}
|
|
221
|
+
let num = 1;
|
|
222
|
+
let distanceInfos = [];
|
|
223
|
+
sortedeMap.forEach((value, key) => {
|
|
224
|
+
let distanceInfo = new AnalysisInfo_1.DistanceInfo();
|
|
225
|
+
distanceInfo.objectNameOrType = objectName;
|
|
226
|
+
distanceInfo.count = value;
|
|
227
|
+
distanceInfo.distance = key;
|
|
228
|
+
distanceInfo.retainedSize = retainSizeMap.get(key);
|
|
229
|
+
distanceInfo.selfSize = selfSizeMap.get(key);
|
|
230
|
+
distanceInfo.retainedSizeTotalHeapPercent = distanceInfo.retainedSize / totalHeapSize * 100;
|
|
231
|
+
distanceInfo.selfSizeTotalHeapPercent = distanceInfo.selfSize / totalHeapSize * 100;
|
|
232
|
+
distanceInfo.retainedSizeTotalRetainedPercent = distanceInfo.retainedSize / totalRetainSize * 100;
|
|
233
|
+
distanceInfo.selfSizeTotalSelfPercent = distanceInfo.selfSize / totalSelfSize * 100;
|
|
234
|
+
distanceInfos.push(distanceInfo);
|
|
235
|
+
console.log(`Index-${num++}, ${distanceInfo.toString()}`);
|
|
236
|
+
});
|
|
237
|
+
let targetNode = new AnalysisInfo_1.StatisticsByDistance();
|
|
238
|
+
targetNode.type = objectName;
|
|
239
|
+
targetNode.desc = `指定类名对象按 Distance 统计`;
|
|
240
|
+
targetNode.totalCount = totalCount;
|
|
241
|
+
targetNode.totalHeapSize = totalHeapSize;
|
|
242
|
+
targetNode.totalRetainedSize = totalRetainSize;
|
|
243
|
+
targetNode.totalSelfSize = totalSelfSize;
|
|
244
|
+
targetNode.distanceInfos = distanceInfos;
|
|
245
|
+
return targetNode;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* 指定类名的最短引用链聚合
|
|
249
|
+
* @param snapshot 快照
|
|
250
|
+
* @param topNum TopN
|
|
251
|
+
*/
|
|
252
|
+
aggregateSpecificObjectNameByReference(snapshot, objectName, topNum = 10) {
|
|
253
|
+
console.log(`\n\n========================${objectName} 对象按最短引用链聚合=========================\n`);
|
|
254
|
+
let totalHeapSize = 0;
|
|
255
|
+
let totalRetainSize = 0;
|
|
256
|
+
let totalSelfSize = 0;
|
|
257
|
+
let totalCount = 0;
|
|
258
|
+
let countMap = new Map();
|
|
259
|
+
let retainSizeMap = new Map();
|
|
260
|
+
let selfSizeMap = new Map();
|
|
261
|
+
snapshot.nodes.forEach((node) => {
|
|
262
|
+
totalHeapSize += node.self_size;
|
|
263
|
+
if (node.name === objectName) {
|
|
264
|
+
totalCount++;
|
|
265
|
+
totalRetainSize += node.retainedSize;
|
|
266
|
+
totalSelfSize += node.self_size;
|
|
267
|
+
let [shortestPathIds, shortestPathStrs] = Finder_1.Finder.getShortestPath(node);
|
|
268
|
+
let shortestPathStr = shortestPathStrs.join(' <- ');
|
|
269
|
+
countMap.set(shortestPathStr, (countMap.get(shortestPathStr) || 0) + 1);
|
|
270
|
+
retainSizeMap.set(shortestPathStr, (retainSizeMap.get(shortestPathStr) || 0) + node.retainedSize);
|
|
271
|
+
selfSizeMap.set(shortestPathStr, (selfSizeMap.get(shortestPathStr) || 0) + node.self_size);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
console.log(`Total Heap Size: ${(totalHeapSize / 1024 / 1024).toFixed(2)} MB`);
|
|
275
|
+
console.log(`Total ${objectName} Self Size: ${(totalSelfSize / 1024).toFixed(2)} KB, Ratio: ${(totalSelfSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
276
|
+
console.log(`Total ${objectName} Retained Size: ${(totalRetainSize / 1024).toFixed(2)} KB, Ratio: ${(totalRetainSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
277
|
+
console.log(`Total ${objectName} Count: ${totalCount}`);
|
|
278
|
+
let sortedeMap;
|
|
279
|
+
if (this.config.sortType === ArkXSortType.BY_COUNT) {
|
|
280
|
+
console.log(`\n${objectName} Info By Count:`);
|
|
281
|
+
sortedeMap = countMap.size < topNum
|
|
282
|
+
? new Map([...countMap].sort((a, b) => b[1] - a[1]))
|
|
283
|
+
: new Map([...countMap].sort((a, b) => b[1] - a[1]).slice(0, topNum));
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
console.log(`\n${objectName} Info By Retained Size:`);
|
|
287
|
+
sortedeMap = retainSizeMap.size < topNum
|
|
288
|
+
? new Map([...retainSizeMap].sort((a, b) => b[1] - a[1]))
|
|
289
|
+
: new Map([...retainSizeMap].sort((a, b) => b[1] - a[1]).slice(0, topNum));
|
|
290
|
+
}
|
|
291
|
+
let num = 1;
|
|
292
|
+
let shortestPathInfos = [];
|
|
293
|
+
sortedeMap.forEach((_, key) => {
|
|
294
|
+
let info = new AnalysisInfo_1.ShortestPathInfo();
|
|
295
|
+
info.shortestPathStr = key;
|
|
296
|
+
info.count = countMap.get(key);
|
|
297
|
+
info.retainedSize = retainSizeMap.get(key);
|
|
298
|
+
info.selfSize = selfSizeMap.get(key);
|
|
299
|
+
info.retainedSizeTotalHeapPercent = info.retainedSize / totalHeapSize * 100;
|
|
300
|
+
info.selfSizeTotalHeapPercent = info.selfSize / totalHeapSize * 100;
|
|
301
|
+
info.retainedSizeTotalRetainedPercent = info.retainedSize / totalRetainSize * 100;
|
|
302
|
+
info.selfSizeTotalSelfPercent = info.selfSize / totalSelfSize * 100;
|
|
303
|
+
shortestPathInfos.push(info);
|
|
304
|
+
console.log(`Index-${num++}, ${info.toString()}`);
|
|
305
|
+
});
|
|
306
|
+
let targetNode = new AnalysisInfo_1.AggregationByShortestPath();
|
|
307
|
+
targetNode.shortestPathInfos = [];
|
|
308
|
+
targetNode.type = objectName;
|
|
309
|
+
targetNode.desc = `按最短引用链聚合`;
|
|
310
|
+
targetNode.totalHeapSize = totalHeapSize;
|
|
311
|
+
targetNode.totalRetainedSize = totalRetainSize;
|
|
312
|
+
targetNode.totalSelfSize = totalSelfSize;
|
|
313
|
+
targetNode.totalCount = totalCount;
|
|
314
|
+
targetNode.shortestPathInfos = shortestPathInfos;
|
|
315
|
+
return targetNode;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* 指定类名的Distance=1的对象属性按最短引用链聚合
|
|
319
|
+
* @param snapshot 快照
|
|
320
|
+
* @param objectName
|
|
321
|
+
* @param topNum TopN
|
|
322
|
+
*/
|
|
323
|
+
aggregateSpecificObjectNameByDistance1(snapshot, objectName, topNum = 10, maxRetainedSize = -1) {
|
|
324
|
+
console.log(`\n========================${objectName} 按 Distance=1 的对象属性聚合分析=========================\n`);
|
|
325
|
+
let totalHeapSize = 0;
|
|
326
|
+
let totalRetainedSize = 0;
|
|
327
|
+
let totalSelfSize = 0;
|
|
328
|
+
let totalCount = 0;
|
|
329
|
+
let countMap = new Map();
|
|
330
|
+
let retainedSizeMap = new Map();
|
|
331
|
+
let selfSizeMap = new Map();
|
|
332
|
+
snapshot.nodes.forEach((node) => {
|
|
333
|
+
totalHeapSize += node.self_size;
|
|
334
|
+
if (node.name !== objectName) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (node.retainedSize / 1024 < maxRetainedSize) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
let distance = Finder_1.Finder.getShortestPath(node)[2];
|
|
341
|
+
if (distance > 1) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
node.forEachReference((edge) => {
|
|
345
|
+
let toNode = edge.toNode;
|
|
346
|
+
totalRetainedSize += toNode.retainedSize;
|
|
347
|
+
totalSelfSize += toNode.self_size;
|
|
348
|
+
totalCount++;
|
|
349
|
+
let [shortestPathIds, shortestPathStrs, distance] = Finder_1.Finder.getShortestPath(toNode);
|
|
350
|
+
let shortestPath = shortestPathStrs.join(' <- ');
|
|
351
|
+
countMap.set(shortestPath, (countMap.get(shortestPath) || 0) + 1);
|
|
352
|
+
retainedSizeMap.set(shortestPath, (retainedSizeMap.get(shortestPath) || 0) + toNode.retainedSize);
|
|
353
|
+
selfSizeMap.set(shortestPath, (selfSizeMap.get(shortestPath) || 0) + toNode.self_size);
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
// 打印总堆大小
|
|
357
|
+
console.log(`Total Heap Size: ${(totalHeapSize / 1024 / 1024).toFixed(2)} MB`);
|
|
358
|
+
console.log(`All Properties Retained Size in ${objectName} Distance=1: ${(totalRetainedSize / 1024).toFixed(2)} KB, Ratio: ${(totalRetainedSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
359
|
+
console.log(`All Properties Self Size in ${objectName} Distance=1: ${(totalSelfSize / 1024).toFixed(2)} KB, Ratio: ${(totalSelfSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
360
|
+
console.log(`Count of Properties in ${objectName} Distance=1: ${totalCount}`);
|
|
361
|
+
let sortedeMap;
|
|
362
|
+
if (this.config.sortType === ArkXSortType.BY_COUNT) {
|
|
363
|
+
console.log(`\n${objectName} Info By Count:`);
|
|
364
|
+
sortedeMap = countMap.size < topNum
|
|
365
|
+
? new Map([...countMap].sort((a, b) => b[1] - a[1]))
|
|
366
|
+
: new Map([...countMap].sort((a, b) => b[1] - a[1]).slice(0, topNum));
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
console.log(`\n${objectName} Info By Retained Size:`);
|
|
370
|
+
sortedeMap = retainedSizeMap.size < topNum
|
|
371
|
+
? new Map([...retainedSizeMap].sort((a, b) => b[1] - a[1]))
|
|
372
|
+
: new Map([...retainedSizeMap].sort((a, b) => b[1] - a[1]).slice(0, topNum));
|
|
373
|
+
}
|
|
374
|
+
let propInfos = [];
|
|
375
|
+
let num = 1;
|
|
376
|
+
sortedeMap.forEach((_, key) => {
|
|
377
|
+
let propInfo = new AnalysisInfo_1.PropertyInfo();
|
|
378
|
+
propInfo.propName = '-';
|
|
379
|
+
propInfo.propShortestPath = key;
|
|
380
|
+
propInfo.retainedSize = retainedSizeMap.get(key);
|
|
381
|
+
propInfo.selfSize = selfSizeMap.get(key);
|
|
382
|
+
propInfo.count = countMap.get(key);
|
|
383
|
+
propInfo.retainedSizeTotalHeapPercent = propInfo.retainedSize / totalHeapSize * 100;
|
|
384
|
+
propInfo.selfSizeTotalHeapPercent = propInfo.selfSize / totalHeapSize * 100;
|
|
385
|
+
propInfo.retainedSizeTotalRetainedPercent = propInfo.retainedSize / totalRetainedSize * 100;
|
|
386
|
+
propInfo.selfSizeTotalSelfPercent = propInfo.selfSize / totalSelfSize * 100;
|
|
387
|
+
propInfos.push(propInfo);
|
|
388
|
+
console.log(`${num++}.${propInfo.toString()}`);
|
|
389
|
+
});
|
|
390
|
+
let targetNode = new AnalysisInfo_1.AggregationByProperty();
|
|
391
|
+
targetNode.type = objectName;
|
|
392
|
+
targetNode.desc = `按 Distance=1 的对象属性聚合`;
|
|
393
|
+
targetNode.totalCount = totalCount;
|
|
394
|
+
targetNode.totalHeapSize = totalHeapSize;
|
|
395
|
+
targetNode.totalRetainedSize = totalRetainedSize;
|
|
396
|
+
targetNode.totalSelfSize = totalSelfSize;
|
|
397
|
+
targetNode.propertyInfos = propInfos;
|
|
398
|
+
return targetNode;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* 指定类名的最短引用链聚合
|
|
402
|
+
* @param snapshot 快照
|
|
403
|
+
* @param topNum TopN
|
|
404
|
+
*/
|
|
405
|
+
aggregateSpecificObjectTypeByReference(snapshot, objectType, topNum = 10) {
|
|
406
|
+
console.log(`\n\n========================${objectType} 类型的对象按最短引用链聚合=========================\n`);
|
|
407
|
+
let totalHeapSize = 0;
|
|
408
|
+
let totalRetainSize = 0;
|
|
409
|
+
let totalSelfSize = 0;
|
|
410
|
+
let totalCount = 0;
|
|
411
|
+
let countMap = new Map();
|
|
412
|
+
let retainSizeMap = new Map();
|
|
413
|
+
let selfSizeMap = new Map();
|
|
414
|
+
snapshot.nodes.forEach((node) => {
|
|
415
|
+
totalHeapSize += node.self_size;
|
|
416
|
+
if (node.type === objectType) {
|
|
417
|
+
totalCount++;
|
|
418
|
+
totalRetainSize += node.retainedSize;
|
|
419
|
+
totalSelfSize += node.self_size;
|
|
420
|
+
let [shortestPathIds, shortestPathStrs] = Finder_1.Finder.getShortestPath(node);
|
|
421
|
+
let shortestPathStr = shortestPathStrs.join(' <- ');
|
|
422
|
+
countMap.set(shortestPathStr, (countMap.get(shortestPathStr) || 0) + 1);
|
|
423
|
+
retainSizeMap.set(shortestPathStr, (retainSizeMap.get(shortestPathStr) || 0) + node.retainedSize);
|
|
424
|
+
selfSizeMap.set(shortestPathStr, (selfSizeMap.get(shortestPathStr) || 0) + node.self_size);
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
console.log(`Total Heap Size: ${(totalHeapSize / 1024 / 1024).toFixed(2)} MB`);
|
|
428
|
+
console.log(`Total Type ${objectType} Self Size: ${(totalSelfSize / 1024).toFixed(2)} KB, Ratio: ${(totalSelfSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
429
|
+
console.log(`Total Type ${objectType} Retained Size: ${(totalRetainSize / 1024).toFixed(2)} KB, Ratio: ${(totalRetainSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
430
|
+
console.log(`Total Type ${objectType} Count: ${totalCount}`);
|
|
431
|
+
let sortedeMap;
|
|
432
|
+
if (this.config.sortType === ArkXSortType.BY_COUNT) {
|
|
433
|
+
console.log(`\nType ${objectType} Info By Count:`);
|
|
434
|
+
sortedeMap = countMap.size < topNum
|
|
435
|
+
? new Map([...countMap].sort((a, b) => b[1] - a[1]))
|
|
436
|
+
: new Map([...countMap].sort((a, b) => b[1] - a[1]).slice(0, topNum));
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
console.log(`\nType ${objectType} Info By Retained Size:`);
|
|
440
|
+
sortedeMap = retainSizeMap.size < topNum
|
|
441
|
+
? new Map([...retainSizeMap].sort((a, b) => b[1] - a[1]))
|
|
442
|
+
: new Map([...retainSizeMap].sort((a, b) => b[1] - a[1]).slice(0, topNum));
|
|
443
|
+
}
|
|
444
|
+
let num = 1;
|
|
445
|
+
let shortestPathInfos = [];
|
|
446
|
+
sortedeMap.forEach((_, key) => {
|
|
447
|
+
let info = new AnalysisInfo_1.ShortestPathInfo();
|
|
448
|
+
info.shortestPathStr = key;
|
|
449
|
+
info.count = countMap.get(key);
|
|
450
|
+
info.retainedSize = retainSizeMap.get(key);
|
|
451
|
+
info.selfSize = selfSizeMap.get(key);
|
|
452
|
+
info.retainedSizeTotalHeapPercent = info.retainedSize / totalHeapSize * 100;
|
|
453
|
+
info.selfSizeTotalHeapPercent = info.selfSize / totalHeapSize * 100;
|
|
454
|
+
info.retainedSizeTotalRetainedPercent = info.retainedSize / totalRetainSize * 100;
|
|
455
|
+
info.selfSizeTotalSelfPercent = info.selfSize / totalSelfSize * 100;
|
|
456
|
+
shortestPathInfos.push(info);
|
|
457
|
+
console.log(`Index-${num++}, ${info.toString()}`);
|
|
458
|
+
});
|
|
459
|
+
let targetNode = new AnalysisInfo_1.AggregationByShortestPath();
|
|
460
|
+
targetNode.type = objectType;
|
|
461
|
+
targetNode.desc = `按最短引用链聚合`;
|
|
462
|
+
targetNode.totalHeapSize = totalHeapSize;
|
|
463
|
+
targetNode.totalRetainedSize = totalRetainSize;
|
|
464
|
+
targetNode.totalSelfSize = totalSelfSize;
|
|
465
|
+
targetNode.totalCount = totalCount;
|
|
466
|
+
targetNode.shortestPathInfos = shortestPathInfos;
|
|
467
|
+
return targetNode;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* 指定类名/类型/标签的最短引用链聚合
|
|
471
|
+
* @param snapshot 快照
|
|
472
|
+
* @param objectName 对象类名,为空则不判断
|
|
473
|
+
* @param objectType 对象类型,为空则不判断
|
|
474
|
+
* @param tags 对象标签,比如业务标签
|
|
475
|
+
* @param topNum TopN
|
|
476
|
+
*/
|
|
477
|
+
aggregateSpecificObjectInfoByReference(snapshot, objectName, objectType, tags, topNum = 10) {
|
|
478
|
+
console.log(`\n\n========================Name:${objectName}-Type:${objectType}-Tags:${tags} 对象按最短引用链聚合=========================\n`);
|
|
479
|
+
let totalHeapSize = 0;
|
|
480
|
+
let totalRetainSize = 0;
|
|
481
|
+
let totalSelfSize = 0;
|
|
482
|
+
let totalCount = 0;
|
|
483
|
+
let countMap = new Map();
|
|
484
|
+
let retainSizeMap = new Map();
|
|
485
|
+
let selfSizeMap = new Map();
|
|
486
|
+
snapshot.nodes.forEach((node) => {
|
|
487
|
+
totalHeapSize += node.self_size;
|
|
488
|
+
if ((node.name === objectName)
|
|
489
|
+
|| (node.type === objectType)
|
|
490
|
+
|| tags.some(tag => node.name.includes(tag))) {
|
|
491
|
+
totalCount++;
|
|
492
|
+
totalRetainSize += node.retainedSize;
|
|
493
|
+
totalSelfSize += node.self_size;
|
|
494
|
+
let [shortestPathIds, shortestPathStrs] = Finder_1.Finder.getShortestPath(node);
|
|
495
|
+
let shortestPathStr = shortestPathStrs.join(' <- ');
|
|
496
|
+
countMap.set(shortestPathStr, (countMap.get(shortestPathStr) || 0) + 1);
|
|
497
|
+
retainSizeMap.set(shortestPathStr, (retainSizeMap.get(shortestPathStr) || 0) + node.retainedSize);
|
|
498
|
+
selfSizeMap.set(shortestPathStr, (selfSizeMap.get(shortestPathStr) || 0) + node.self_size);
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
console.log(`Total Heap Size: ${(totalHeapSize / 1024 / 1024).toFixed(2)} MB`);
|
|
502
|
+
console.log(`Total Self Size: ${(totalSelfSize / 1024).toFixed(2)} KB, Ratio: ${(totalSelfSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
503
|
+
console.log(`Total Retained Size: ${(totalRetainSize / 1024).toFixed(2)} KB, Ratio: ${(totalRetainSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
504
|
+
console.log(`Total Count: ${totalCount}`);
|
|
505
|
+
let sortedeMap;
|
|
506
|
+
if (this.config.sortType === ArkXSortType.BY_COUNT) {
|
|
507
|
+
console.log(`\nInfo By Count:`);
|
|
508
|
+
sortedeMap = countMap.size < topNum
|
|
509
|
+
? new Map([...countMap].sort((a, b) => b[1] - a[1]))
|
|
510
|
+
: new Map([...countMap].sort((a, b) => b[1] - a[1]).slice(0, topNum));
|
|
511
|
+
}
|
|
512
|
+
else {
|
|
513
|
+
console.log(`\nInfo By Retained Size:`);
|
|
514
|
+
sortedeMap = retainSizeMap.size < topNum
|
|
515
|
+
? new Map([...retainSizeMap].sort((a, b) => b[1] - a[1]))
|
|
516
|
+
: new Map([...retainSizeMap].sort((a, b) => b[1] - a[1]).slice(0, topNum));
|
|
517
|
+
}
|
|
518
|
+
let num = 1;
|
|
519
|
+
let shortestPathInfos = [];
|
|
520
|
+
sortedeMap.forEach((_, key) => {
|
|
521
|
+
let info = new AnalysisInfo_1.ShortestPathInfo();
|
|
522
|
+
info.shortestPathStr = key;
|
|
523
|
+
info.count = countMap.get(key);
|
|
524
|
+
info.retainedSize = retainSizeMap.get(key);
|
|
525
|
+
info.selfSize = selfSizeMap.get(key);
|
|
526
|
+
info.retainedSizeTotalHeapPercent = info.retainedSize / totalHeapSize * 100;
|
|
527
|
+
info.selfSizeTotalHeapPercent = info.selfSize / totalHeapSize * 100;
|
|
528
|
+
info.retainedSizeTotalRetainedPercent = info.retainedSize / totalRetainSize * 100;
|
|
529
|
+
info.selfSizeTotalSelfPercent = info.selfSize / totalSelfSize * 100;
|
|
530
|
+
shortestPathInfos.push(info);
|
|
531
|
+
console.log(`Index-${num++}, ${info.toString()}`);
|
|
532
|
+
});
|
|
533
|
+
let targetNode = new AnalysisInfo_1.AggregationByShortestPath();
|
|
534
|
+
targetNode.type = `[Name:${objectName}-Type:${objectType}-Tags:${tags}]`;
|
|
535
|
+
targetNode.desc = `按指定类名/类型/标签的对象的最短引用链聚合`;
|
|
536
|
+
targetNode.totalHeapSize = totalHeapSize;
|
|
537
|
+
targetNode.totalRetainedSize = totalRetainSize;
|
|
538
|
+
targetNode.totalSelfSize = totalSelfSize;
|
|
539
|
+
targetNode.totalCount = totalCount;
|
|
540
|
+
targetNode.shortestPathInfos = shortestPathInfos;
|
|
541
|
+
return targetNode;
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* 指定类名/类型/标签的最短引用链聚合
|
|
545
|
+
* @param snapshot 快照
|
|
546
|
+
* @param objectType 对象类型,为空则不判断
|
|
547
|
+
* @param tags 对象标签,比如业务标签
|
|
548
|
+
* @param topNum TopN
|
|
549
|
+
*/
|
|
550
|
+
aggregateSpecificObjectInfoByClassName(snapshot, objectType, tags, topNum = 10) {
|
|
551
|
+
console.log(`\n\n========================Type:${objectType}-Tags:${tags} 对象按对象名称聚合=========================\n`);
|
|
552
|
+
let totalHeapSize = 0;
|
|
553
|
+
let totalRetainSize = 0;
|
|
554
|
+
let totalSelfSize = 0;
|
|
555
|
+
let totalCount = 0;
|
|
556
|
+
let countMap = new Map();
|
|
557
|
+
let retainSizeMap = new Map();
|
|
558
|
+
let selfSizeMap = new Map();
|
|
559
|
+
snapshot.nodes.forEach((node) => {
|
|
560
|
+
totalHeapSize += node.self_size;
|
|
561
|
+
if ((node.type === objectType) || tags.some(tag => node.name.includes(tag))) {
|
|
562
|
+
totalCount++;
|
|
563
|
+
totalRetainSize += node.retainedSize;
|
|
564
|
+
totalSelfSize += node.self_size;
|
|
565
|
+
let name = Finder_1.Finder.getClassName(node.name);
|
|
566
|
+
countMap.set(name, (countMap.get(name) || 0) + 1);
|
|
567
|
+
retainSizeMap.set(name, (retainSizeMap.get(name) || 0) + node.retainedSize);
|
|
568
|
+
selfSizeMap.set(name, (selfSizeMap.get(name) || 0) + node.self_size);
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
console.log(`Total Heap Size: ${(totalHeapSize / 1024 / 1024).toFixed(2)} MB`);
|
|
572
|
+
console.log(`Total Self Size: ${(totalSelfSize / 1024).toFixed(2)} KB, Ratio: ${(totalSelfSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
573
|
+
console.log(`Total Retained Size: ${(totalRetainSize / 1024).toFixed(2)} KB, Ratio: ${(totalRetainSize / totalHeapSize * 100).toFixed(2)}%`);
|
|
574
|
+
console.log(`Total Count: ${totalCount}`);
|
|
575
|
+
let sortedeMap;
|
|
576
|
+
if (this.config.sortType === ArkXSortType.BY_COUNT) {
|
|
577
|
+
console.log(`\nInfo By Count:`);
|
|
578
|
+
sortedeMap = countMap.size < topNum
|
|
579
|
+
? new Map([...countMap].sort((a, b) => b[1] - a[1]))
|
|
580
|
+
: new Map([...countMap].sort((a, b) => b[1] - a[1]).slice(0, topNum));
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
console.log(`\nInfo By Retained Size:`);
|
|
584
|
+
sortedeMap = retainSizeMap.size < topNum
|
|
585
|
+
? new Map([...retainSizeMap].sort((a, b) => b[1] - a[1]))
|
|
586
|
+
: new Map([...retainSizeMap].sort((a, b) => b[1] - a[1]).slice(0, topNum));
|
|
587
|
+
}
|
|
588
|
+
let num = 1;
|
|
589
|
+
let classInfos = [];
|
|
590
|
+
sortedeMap.forEach((_, key) => {
|
|
591
|
+
let info = new AnalysisInfo_1.ClassInfo();
|
|
592
|
+
info.className = key;
|
|
593
|
+
info.count = countMap.get(key);
|
|
594
|
+
info.retainedSize = retainSizeMap.get(key);
|
|
595
|
+
info.selfSize = selfSizeMap.get(key);
|
|
596
|
+
info.retainedSizeTotalHeapPercent = info.retainedSize / totalHeapSize * 100;
|
|
597
|
+
info.selfSizeTotalHeapPercent = info.selfSize / totalHeapSize * 100;
|
|
598
|
+
info.retainedSizeTotalRetainedPercent = info.retainedSize / totalRetainSize * 100;
|
|
599
|
+
info.selfSizeTotalSelfPercent = info.selfSize / totalSelfSize * 100;
|
|
600
|
+
classInfos.push(info);
|
|
601
|
+
console.log(`Index-${num++}, ${info.toString()}`);
|
|
602
|
+
});
|
|
603
|
+
let targetNode = new AnalysisInfo_1.AggregationByClassName();
|
|
604
|
+
targetNode.type = `[Type:${objectType}-Tags:${tags}]`;
|
|
605
|
+
targetNode.desc = `按对象类型/标签聚合`;
|
|
606
|
+
targetNode.totalHeapSize = totalHeapSize;
|
|
607
|
+
targetNode.totalRetainedSize = totalRetainSize;
|
|
608
|
+
targetNode.totalSelfSize = totalSelfSize;
|
|
609
|
+
targetNode.totalCount = totalCount;
|
|
610
|
+
targetNode.classInfos = classInfos;
|
|
611
|
+
return targetNode;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
exports.ArkXAnalyzer = ArkXAnalyzer;
|
|
615
|
+
ArkXAnalyzer.NAME = 'ark-x-analyzer';
|
|
616
|
+
ArkXAnalyzer.DESC = "Analyze heapsnapshot files and aggregate & statistics.";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analyzer interface
|
|
3
|
+
*/
|
|
4
|
+
export interface IAnalyzer {
|
|
5
|
+
/**
|
|
6
|
+
* initialize command program
|
|
7
|
+
* @param proc command
|
|
8
|
+
*/
|
|
9
|
+
analyze(args: any[]): any;
|
|
10
|
+
/**
|
|
11
|
+
* set configuration
|
|
12
|
+
* @param cfg configuration
|
|
13
|
+
*/
|
|
14
|
+
setConfig(cfg: any): void;
|
|
15
|
+
/**
|
|
16
|
+
* get configuration
|
|
17
|
+
* @return configuration
|
|
18
|
+
*/
|
|
19
|
+
getConfig(): any;
|
|
20
|
+
/**
|
|
21
|
+
* get type
|
|
22
|
+
*/
|
|
23
|
+
getType(): string;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=IAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/IAnalyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,GAAI,GAAG,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,GAAG,GAAI,IAAI,CAAC;IAE3B;;;OAGG;IACH,SAAS,IAAI,GAAG,CAAC;IAEjB;;OAEG;IACH,OAAO,IAAI,MAAM,CAAC;CACrB"}
|