@memlab/core 1.0.5 → 1.0.9
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 +17 -0
- package/dist/index.js +17 -0
- package/dist/lib/Config.d.ts +5 -2
- package/dist/lib/Config.js +11 -2
- package/dist/lib/FileManager.d.ts +2 -0
- package/dist/lib/FileManager.js +1 -0
- package/dist/lib/HeapAnalyzer.d.ts +2 -2
- package/dist/lib/HeapAnalyzer.js +27 -60
- package/dist/lib/InternalValueSetter.d.ts +2 -0
- package/dist/lib/InternalValueSetter.js +2 -0
- package/dist/lib/Types.d.ts +63 -6
- package/dist/lib/Utils.js +24 -1
- package/dist/lib/leak-filters/BaseLeakFilter.rule.d.ts +24 -0
- package/dist/lib/leak-filters/BaseLeakFilter.rule.js +22 -0
- package/dist/lib/leak-filters/LeakFilterRuleList.d.ts +13 -0
- package/dist/lib/leak-filters/LeakFilterRuleList.js +33 -0
- package/dist/lib/leak-filters/LeakObjectFilter.d.ts +19 -0
- package/dist/lib/leak-filters/LeakObjectFilter.js +36 -0
- package/dist/lib/leak-filters/rules/FilterByExternalFilter.rule.d.ts +19 -0
- package/dist/lib/leak-filters/rules/FilterByExternalFilter.rule.js +27 -0
- package/dist/lib/leak-filters/rules/FilterDetachedDOMElement.rule.d.ts +20 -0
- package/dist/lib/leak-filters/rules/FilterDetachedDOMElement.rule.js +40 -0
- package/dist/lib/leak-filters/rules/FilterHermesNode.rule.d.ts +16 -0
- package/dist/lib/leak-filters/rules/FilterHermesNode.rule.js +27 -0
- package/dist/lib/leak-filters/rules/FilterOverSizedNodeAsLeak.rule.d.ts +19 -0
- package/dist/lib/leak-filters/rules/FilterOverSizedNodeAsLeak.rule.js +27 -0
- package/dist/lib/leak-filters/rules/FilterStackTraceFrame.rule.d.ts +19 -0
- package/dist/lib/leak-filters/rules/FilterStackTraceFrame.rule.js +28 -0
- package/dist/lib/leak-filters/rules/FilterTrivialNode.rule.d.ts +20 -0
- package/dist/lib/leak-filters/rules/FilterTrivialNode.rule.js +33 -0
- package/dist/lib/leak-filters/rules/FilterUnmountedFiberNode.rule.d.ts +20 -0
- package/dist/lib/leak-filters/rules/FilterUnmountedFiberNode.rule.js +37 -0
- package/dist/trace-cluster/TraceBucket.d.ts +1 -0
- package/dist/trace-cluster/TraceBucket.js +12 -1
- package/package.json +1 -1
- package/dist/__tests__/parser/HeapParser.test.d.ts.map +0 -1
- package/dist/__tests__/parser/NodeHeap.test.d.ts.map +0 -1
- package/dist/__tests__/parser/StringNode.test.d.ts.map +0 -1
- package/dist/__tests__/parser/traverse/HeapNodeTraverse.test.d.ts.map +0 -1
- package/dist/__tests__/utils/utils.test.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/BaseOption.d.ts.map +0 -1
- package/dist/lib/BrowserInfo.d.ts.map +0 -1
- package/dist/lib/Config.d.ts.map +0 -1
- package/dist/lib/Console.d.ts.map +0 -1
- package/dist/lib/Constant.d.ts.map +0 -1
- package/dist/lib/FileManager.d.ts.map +0 -1
- package/dist/lib/HeapAnalyzer.d.ts.map +0 -1
- package/dist/lib/HeapParser.d.ts.map +0 -1
- package/dist/lib/InternalValueSetter.d.ts.map +0 -1
- package/dist/lib/NodeHeap.d.ts.map +0 -1
- package/dist/lib/ProcessManager.d.ts.map +0 -1
- package/dist/lib/Serializer.d.ts.map +0 -1
- package/dist/lib/StringLoader.d.ts.map +0 -1
- package/dist/lib/Types.d.ts.map +0 -1
- package/dist/lib/Utils.d.ts.map +0 -1
- package/dist/lib/heap-data/HeapEdge.d.ts.map +0 -1
- package/dist/lib/heap-data/HeapLocation.d.ts.map +0 -1
- package/dist/lib/heap-data/HeapNode.d.ts.map +0 -1
- package/dist/lib/heap-data/HeapSnapshot.d.ts.map +0 -1
- package/dist/lib/heap-data/HeapStringNode.d.ts.map +0 -1
- package/dist/lib/heap-data/HeapUtils.d.ts.map +0 -1
- package/dist/logger/LeakClusterLogger.d.ts.map +0 -1
- package/dist/logger/LeakTraceDetailsLogger.d.ts.map +0 -1
- package/dist/modes/BaseMode.d.ts.map +0 -1
- package/dist/modes/InteractionTestMode.d.ts.map +0 -1
- package/dist/modes/MeasureMode.d.ts.map +0 -1
- package/dist/modes/RunningModes.d.ts.map +0 -1
- package/dist/paths/TraceFinder.d.ts.map +0 -1
- package/dist/trace-cluster/ClusterUtils.d.ts.map +0 -1
- package/dist/trace-cluster/ClusterUtilsHelper.d.ts.map +0 -1
- package/dist/trace-cluster/ClusteringHeuristics.d.ts.map +0 -1
- package/dist/trace-cluster/EvalutationMetric.d.ts.map +0 -1
- package/dist/trace-cluster/TraceBucket.d.ts.map +0 -1
- package/dist/trace-cluster/TraceElement.d.ts.map +0 -1
- package/dist/trace-cluster/strategies/TraceAsClusterStrategy.d.ts.map +0 -1
- package/dist/trace-cluster/strategies/TraceSimilarityStrategy.d.ts.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,22 +8,39 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
export * from './lib/Types';
|
|
11
|
+
/** @internal */
|
|
11
12
|
export { default as config } from './lib/Config';
|
|
13
|
+
/** @internal */
|
|
12
14
|
export * from './lib/InternalValueSetter';
|
|
15
|
+
/** @internal */
|
|
13
16
|
export * from './lib/Config';
|
|
17
|
+
/** @internal */
|
|
14
18
|
export { default as info } from './lib/Console';
|
|
19
|
+
/** @internal */
|
|
15
20
|
export { default as BaseOption } from './lib/BaseOption';
|
|
21
|
+
/** @internal */
|
|
16
22
|
export { default as utils } from './lib/Utils';
|
|
23
|
+
/** @internal */
|
|
17
24
|
export { default as fileManager } from './lib/FileManager';
|
|
25
|
+
/** @internal */
|
|
18
26
|
export * from './lib/FileManager';
|
|
27
|
+
/** @internal */
|
|
19
28
|
export { default as serializer } from './lib/Serializer';
|
|
29
|
+
/** @internal */
|
|
20
30
|
export { default as browserInfo } from './lib/BrowserInfo';
|
|
31
|
+
/** @internal */
|
|
21
32
|
export { default as analysis } from './lib/HeapAnalyzer';
|
|
33
|
+
/** @internal */
|
|
22
34
|
export { default as constant } from './lib/Constant';
|
|
35
|
+
/** @internal */
|
|
23
36
|
export { default as modes } from './modes/RunningModes';
|
|
37
|
+
/** @internal */
|
|
24
38
|
export { default as ProcessManager } from './lib/ProcessManager';
|
|
39
|
+
/** @internal */
|
|
25
40
|
export { default as leakClusterLogger } from './logger/LeakClusterLogger';
|
|
41
|
+
/** @internal */
|
|
26
42
|
export { default as NormalizedTrace } from './trace-cluster/TraceBucket';
|
|
43
|
+
/** @internal */
|
|
27
44
|
export { default as EvaluationMetric } from './trace-cluster/EvalutationMetric';
|
|
28
45
|
export * from './lib/NodeHeap';
|
|
29
46
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -28,35 +28,52 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.EvaluationMetric = exports.NormalizedTrace = exports.leakClusterLogger = exports.ProcessManager = exports.modes = exports.constant = exports.analysis = exports.browserInfo = exports.serializer = exports.fileManager = exports.utils = exports.BaseOption = exports.info = exports.config = void 0;
|
|
30
30
|
__exportStar(require("./lib/Types"), exports);
|
|
31
|
+
/** @internal */
|
|
31
32
|
var Config_1 = require("./lib/Config");
|
|
32
33
|
Object.defineProperty(exports, "config", { enumerable: true, get: function () { return __importDefault(Config_1).default; } });
|
|
34
|
+
/** @internal */
|
|
33
35
|
__exportStar(require("./lib/InternalValueSetter"), exports);
|
|
36
|
+
/** @internal */
|
|
34
37
|
__exportStar(require("./lib/Config"), exports);
|
|
38
|
+
/** @internal */
|
|
35
39
|
var Console_1 = require("./lib/Console");
|
|
36
40
|
Object.defineProperty(exports, "info", { enumerable: true, get: function () { return __importDefault(Console_1).default; } });
|
|
41
|
+
/** @internal */
|
|
37
42
|
var BaseOption_1 = require("./lib/BaseOption");
|
|
38
43
|
Object.defineProperty(exports, "BaseOption", { enumerable: true, get: function () { return __importDefault(BaseOption_1).default; } });
|
|
44
|
+
/** @internal */
|
|
39
45
|
var Utils_1 = require("./lib/Utils");
|
|
40
46
|
Object.defineProperty(exports, "utils", { enumerable: true, get: function () { return __importDefault(Utils_1).default; } });
|
|
47
|
+
/** @internal */
|
|
41
48
|
var FileManager_1 = require("./lib/FileManager");
|
|
42
49
|
Object.defineProperty(exports, "fileManager", { enumerable: true, get: function () { return __importDefault(FileManager_1).default; } });
|
|
50
|
+
/** @internal */
|
|
43
51
|
__exportStar(require("./lib/FileManager"), exports);
|
|
52
|
+
/** @internal */
|
|
44
53
|
var Serializer_1 = require("./lib/Serializer");
|
|
45
54
|
Object.defineProperty(exports, "serializer", { enumerable: true, get: function () { return __importDefault(Serializer_1).default; } });
|
|
55
|
+
/** @internal */
|
|
46
56
|
var BrowserInfo_1 = require("./lib/BrowserInfo");
|
|
47
57
|
Object.defineProperty(exports, "browserInfo", { enumerable: true, get: function () { return __importDefault(BrowserInfo_1).default; } });
|
|
58
|
+
/** @internal */
|
|
48
59
|
var HeapAnalyzer_1 = require("./lib/HeapAnalyzer");
|
|
49
60
|
Object.defineProperty(exports, "analysis", { enumerable: true, get: function () { return __importDefault(HeapAnalyzer_1).default; } });
|
|
61
|
+
/** @internal */
|
|
50
62
|
var Constant_1 = require("./lib/Constant");
|
|
51
63
|
Object.defineProperty(exports, "constant", { enumerable: true, get: function () { return __importDefault(Constant_1).default; } });
|
|
64
|
+
/** @internal */
|
|
52
65
|
var RunningModes_1 = require("./modes/RunningModes");
|
|
53
66
|
Object.defineProperty(exports, "modes", { enumerable: true, get: function () { return __importDefault(RunningModes_1).default; } });
|
|
67
|
+
/** @internal */
|
|
54
68
|
var ProcessManager_1 = require("./lib/ProcessManager");
|
|
55
69
|
Object.defineProperty(exports, "ProcessManager", { enumerable: true, get: function () { return __importDefault(ProcessManager_1).default; } });
|
|
70
|
+
/** @internal */
|
|
56
71
|
var LeakClusterLogger_1 = require("./logger/LeakClusterLogger");
|
|
57
72
|
Object.defineProperty(exports, "leakClusterLogger", { enumerable: true, get: function () { return __importDefault(LeakClusterLogger_1).default; } });
|
|
73
|
+
/** @internal */
|
|
58
74
|
var TraceBucket_1 = require("./trace-cluster/TraceBucket");
|
|
59
75
|
Object.defineProperty(exports, "NormalizedTrace", { enumerable: true, get: function () { return __importDefault(TraceBucket_1).default; } });
|
|
76
|
+
/** @internal */
|
|
60
77
|
var EvalutationMetric_1 = require("./trace-cluster/EvalutationMetric");
|
|
61
78
|
Object.defineProperty(exports, "EvaluationMetric", { enumerable: true, get: function () { return __importDefault(EvalutationMetric_1).default; } });
|
|
62
79
|
__exportStar(require("./lib/NodeHeap"), exports);
|
package/dist/lib/Config.d.ts
CHANGED
|
@@ -37,10 +37,12 @@ interface Device {
|
|
|
37
37
|
declare type ConfigOption = {
|
|
38
38
|
workDir?: string;
|
|
39
39
|
};
|
|
40
|
+
/** @internal */
|
|
40
41
|
export declare enum ErrorHandling {
|
|
41
42
|
Halt = 1,
|
|
42
43
|
Throw = 2
|
|
43
44
|
}
|
|
45
|
+
/** @internal */
|
|
44
46
|
export declare class MemLabConfig {
|
|
45
47
|
snapshotHasDetachedness: boolean;
|
|
46
48
|
specifiedEngine: boolean;
|
|
@@ -165,6 +167,7 @@ export declare class MemLabConfig {
|
|
|
165
167
|
nodeIgnoreSetInShape: Set<string>;
|
|
166
168
|
oversizeObjectAsLeak: boolean;
|
|
167
169
|
oversizeThreshold: number;
|
|
170
|
+
clusterRetainedSizeThreshold: number;
|
|
168
171
|
_isFullRun: boolean;
|
|
169
172
|
_scenario: Optional<IScenario>;
|
|
170
173
|
externalLeakFilter?: Optional<ILeakFilter>;
|
|
@@ -199,8 +202,8 @@ export declare class MemLabConfig {
|
|
|
199
202
|
enableXvfb(display: string): void;
|
|
200
203
|
disableXvfb(): void;
|
|
201
204
|
}
|
|
202
|
-
/** @
|
|
205
|
+
/** @internal */
|
|
203
206
|
declare const config: MemLabConfig;
|
|
204
|
-
/** @
|
|
207
|
+
/** @internal */
|
|
205
208
|
export default config;
|
|
206
209
|
//# sourceMappingURL=Config.d.ts.map
|
package/dist/lib/Config.js
CHANGED
|
@@ -33,11 +33,13 @@ const defaultViewport = {
|
|
|
33
33
|
height: windowHeight,
|
|
34
34
|
deviceScaleFactor: 1,
|
|
35
35
|
};
|
|
36
|
+
/** @internal */
|
|
36
37
|
var ErrorHandling;
|
|
37
38
|
(function (ErrorHandling) {
|
|
38
39
|
ErrorHandling[ErrorHandling["Halt"] = 1] = "Halt";
|
|
39
40
|
ErrorHandling[ErrorHandling["Throw"] = 2] = "Throw";
|
|
40
41
|
})(ErrorHandling = exports.ErrorHandling || (exports.ErrorHandling = {}));
|
|
42
|
+
/** @internal */
|
|
41
43
|
class MemLabConfig {
|
|
42
44
|
constructor(options = {}) {
|
|
43
45
|
// init properties, they can be configured manually
|
|
@@ -47,6 +49,7 @@ class MemLabConfig {
|
|
|
47
49
|
}
|
|
48
50
|
initInternalConfigs() {
|
|
49
51
|
// DO NOT SET PARAMETER HERE
|
|
52
|
+
this._isFullRun = false;
|
|
50
53
|
this._reportLeaksInTimers = false;
|
|
51
54
|
this._deviceManualOverridden = false;
|
|
52
55
|
this._timerNodes = ['Pending activities'];
|
|
@@ -66,6 +69,8 @@ class MemLabConfig {
|
|
|
66
69
|
devtools: this.openDevtoolsConsole,
|
|
67
70
|
// IMPORTANT: test ContinuousTest before change this config
|
|
68
71
|
ignoreHTTPSErrors: true,
|
|
72
|
+
// Support running on Windows
|
|
73
|
+
ignoreDefaultArgs: ['--disable-extensions'],
|
|
69
74
|
userDataDir: this.userDataDir,
|
|
70
75
|
// Chromium in ContinuousTest needs this args
|
|
71
76
|
args: [
|
|
@@ -237,6 +242,7 @@ class MemLabConfig {
|
|
|
237
242
|
this.nodeNameGreyList = new Set([
|
|
238
243
|
'InternalNode',
|
|
239
244
|
'Pending activities',
|
|
245
|
+
'StyleEngine',
|
|
240
246
|
...Constant_1.default.V8SyntheticRoots,
|
|
241
247
|
]);
|
|
242
248
|
// edge names less preferable in trace finding
|
|
@@ -264,6 +270,9 @@ class MemLabConfig {
|
|
|
264
270
|
this.oversizeObjectAsLeak = false;
|
|
265
271
|
// if larger than this threshold, consider as memory leak
|
|
266
272
|
this.oversizeThreshold = 0;
|
|
273
|
+
// only report leak clusters with aggregated retained size
|
|
274
|
+
// bigger than this threshold
|
|
275
|
+
this.clusterRetainedSizeThreshold = 0;
|
|
267
276
|
// initialize file and directory paths
|
|
268
277
|
FileManager_1.default.initDirs(this, options);
|
|
269
278
|
}
|
|
@@ -422,8 +431,8 @@ class MemLabConfig {
|
|
|
422
431
|
}
|
|
423
432
|
}
|
|
424
433
|
exports.MemLabConfig = MemLabConfig;
|
|
425
|
-
/** @
|
|
434
|
+
/** @internal */
|
|
426
435
|
const config = MemLabConfig.getInstance();
|
|
427
436
|
(0, InternalValueSetter_1.setInternalValue)(config, __filename, Constant_1.default.internalDir);
|
|
428
|
-
/** @
|
|
437
|
+
/** @internal */
|
|
429
438
|
exports.default = config;
|
|
@@ -9,11 +9,13 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { MemLabConfig } from './Config';
|
|
11
11
|
import type { AnyValue, Optional } from './Types';
|
|
12
|
+
/** @internal */
|
|
12
13
|
export declare type FileOption = {
|
|
13
14
|
workDir?: Optional<string>;
|
|
14
15
|
clear?: boolean;
|
|
15
16
|
transcient?: boolean;
|
|
16
17
|
};
|
|
18
|
+
/** @internal */
|
|
17
19
|
export declare class FileManager {
|
|
18
20
|
getDefaultWorkDir(): string;
|
|
19
21
|
generateTmpHeapDir(): string;
|
package/dist/lib/FileManager.js
CHANGED
|
@@ -27,8 +27,6 @@ declare class MemoryAnalyst {
|
|
|
27
27
|
preparePathFinder(snapshot: IHeapSnapshot): TraceFinder;
|
|
28
28
|
private dumpPageInteractionSummary;
|
|
29
29
|
private dumpLeakSummaryToConsole;
|
|
30
|
-
private checkDetachedFiberNode;
|
|
31
|
-
private isTrivialNode;
|
|
32
30
|
private filterLeakedObjects;
|
|
33
31
|
aggregateDominatorMetrics(ids: HeapNodeIdSet, snapshot: IHeapSnapshot, checkNodeCb: (node: IHeapNode) => boolean, nodeMetricsCb: (node: IHeapNode) => number): number;
|
|
34
32
|
private getOverallHeapInfo;
|
|
@@ -38,6 +36,8 @@ declare class MemoryAnalyst {
|
|
|
38
36
|
private breakDownSnapshotByShapes;
|
|
39
37
|
private isTrivialEdgeForBreakDown;
|
|
40
38
|
private breakDownByReferrers;
|
|
39
|
+
private printHeapAndLeakInfo;
|
|
40
|
+
private logLeakTraceSummary;
|
|
41
41
|
searchLeakedTraces(leakedNodeIds: HeapNodeIdSet, snapshot: IHeapSnapshot): Promise<{
|
|
42
42
|
paths: LeakTracePathItem[];
|
|
43
43
|
}>;
|
package/dist/lib/HeapAnalyzer.js
CHANGED
|
@@ -32,6 +32,7 @@ const Config_1 = __importDefault(require("./Config"));
|
|
|
32
32
|
const Console_1 = __importDefault(require("./Console"));
|
|
33
33
|
const Serializer_1 = __importDefault(require("./Serializer"));
|
|
34
34
|
const Utils_1 = __importDefault(require("./Utils"));
|
|
35
|
+
const LeakObjectFilter_1 = require("./leak-filters/LeakObjectFilter");
|
|
35
36
|
class MemoryAnalyst {
|
|
36
37
|
checkLeak() {
|
|
37
38
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -416,53 +417,15 @@ class MemoryAnalyst {
|
|
|
416
417
|
Console_1.default.topLevel('Alive objects allocated in target page:');
|
|
417
418
|
Console_1.default.table(list);
|
|
418
419
|
}
|
|
419
|
-
checkDetachedFiberNode(node) {
|
|
420
|
-
if (!Config_1.default.detectFiberNodeLeak ||
|
|
421
|
-
!Utils_1.default.isFiberNode(node) ||
|
|
422
|
-
Utils_1.default.hasHostRoot(node)) {
|
|
423
|
-
return false;
|
|
424
|
-
}
|
|
425
|
-
return !Utils_1.default.isNodeDominatedByDeletionsArray(node);
|
|
426
|
-
}
|
|
427
|
-
isTrivialNode(node) {
|
|
428
|
-
return (node.type === 'number' ||
|
|
429
|
-
Utils_1.default.isStringNode(node) ||
|
|
430
|
-
node.type === 'hidden');
|
|
431
|
-
}
|
|
432
420
|
filterLeakedObjects(leakedNodeIds, snapshot) {
|
|
433
421
|
var _a;
|
|
434
422
|
// call init leak filter hook if exists
|
|
435
423
|
if ((_a = Config_1.default.externalLeakFilter) === null || _a === void 0 ? void 0 : _a.beforeLeakFilter) {
|
|
436
424
|
Config_1.default.externalLeakFilter.beforeLeakFilter(snapshot, leakedNodeIds);
|
|
437
425
|
}
|
|
426
|
+
const leakFilter = new LeakObjectFilter_1.LeakObjectFilter();
|
|
438
427
|
// start filtering memory leaks
|
|
439
|
-
Utils_1.default.filterNodesInPlace(leakedNodeIds, snapshot, node =>
|
|
440
|
-
// use external leak filter if exists
|
|
441
|
-
if (Config_1.default.externalLeakFilter) {
|
|
442
|
-
return Config_1.default.externalLeakFilter.leakFilter(node, snapshot, leakedNodeIds);
|
|
443
|
-
}
|
|
444
|
-
if (this.isTrivialNode(node)) {
|
|
445
|
-
return false;
|
|
446
|
-
}
|
|
447
|
-
// when analyzing hermes heap snapshots, filter Hermes internal objects
|
|
448
|
-
if (Config_1.default.jsEngine === 'hermes' && Utils_1.default.isHermesInternalObject(node)) {
|
|
449
|
-
return false;
|
|
450
|
-
}
|
|
451
|
-
if (Config_1.default.oversizeObjectAsLeak) {
|
|
452
|
-
return node.retainedSize > Config_1.default.oversizeThreshold;
|
|
453
|
-
}
|
|
454
|
-
// check FiberNodes without a Fiber Root
|
|
455
|
-
if (this.checkDetachedFiberNode(node)) {
|
|
456
|
-
return true;
|
|
457
|
-
}
|
|
458
|
-
const isDetached = Utils_1.default.isDetachedDOMNode(node, {
|
|
459
|
-
ignoreInternalNode: true,
|
|
460
|
-
});
|
|
461
|
-
if (isDetached && Config_1.default.targetApp === 'ads-manager') {
|
|
462
|
-
return Utils_1.default.hasReactEdges(node);
|
|
463
|
-
}
|
|
464
|
-
return isDetached || Utils_1.default.isStackTraceFrame(node);
|
|
465
|
-
});
|
|
428
|
+
Utils_1.default.filterNodesInPlace(leakedNodeIds, snapshot, node => leakFilter.filter(Config_1.default, node, snapshot, leakedNodeIds));
|
|
466
429
|
if (Config_1.default.verbose) {
|
|
467
430
|
Console_1.default.midLevel(`${leakedNodeIds.size} Fiber nodes and Detached elements`);
|
|
468
431
|
}
|
|
@@ -615,29 +578,40 @@ class MemoryAnalyst {
|
|
|
615
578
|
.join('\n');
|
|
616
579
|
return referrerInfo;
|
|
617
580
|
}
|
|
581
|
+
printHeapAndLeakInfo(leakedNodeIds, snapshot) {
|
|
582
|
+
// write page interaction summary to the leaks text file
|
|
583
|
+
this.dumpPageInteractionSummary();
|
|
584
|
+
// dump leak summry to console
|
|
585
|
+
this.dumpLeakSummaryToConsole(leakedNodeIds, snapshot);
|
|
586
|
+
// get aggregated leak info
|
|
587
|
+
const heapInfo = this.getOverallHeapInfo(snapshot);
|
|
588
|
+
if (heapInfo) {
|
|
589
|
+
this.printHeapInfo(heapInfo);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
logLeakTraceSummary(trace, nodeIdInPaths, snapshot) {
|
|
593
|
+
if (!Config_1.default.isFullRun) {
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
// convert the path to a string
|
|
597
|
+
const pathStr = Serializer_1.default.summarizePath(trace, nodeIdInPaths, snapshot);
|
|
598
|
+
fs_1.default.appendFileSync(Config_1.default.exploreResultFile, `\n\n${pathStr}\n\n`, 'UTF-8');
|
|
599
|
+
}
|
|
618
600
|
// find unique paths of leaked nodes
|
|
619
601
|
searchLeakedTraces(leakedNodeIds, snapshot) {
|
|
620
602
|
return __awaiter(this, void 0, void 0, function* () {
|
|
621
603
|
const finder = this.preparePathFinder(snapshot);
|
|
622
|
-
|
|
623
|
-
this.dumpPageInteractionSummary();
|
|
624
|
-
// dump leak summry to console
|
|
625
|
-
this.dumpLeakSummaryToConsole(leakedNodeIds, snapshot);
|
|
604
|
+
this.printHeapAndLeakInfo(leakedNodeIds, snapshot);
|
|
626
605
|
// get all leaked objects
|
|
627
606
|
this.filterLeakedObjects(leakedNodeIds, snapshot);
|
|
628
|
-
// get aggregated leak info
|
|
629
|
-
const leakInfo = this.getOverallHeapInfo(snapshot);
|
|
630
|
-
if (leakInfo) {
|
|
631
|
-
this.printHeapInfo(leakInfo);
|
|
632
|
-
}
|
|
633
607
|
if (Config_1.default.verbose) {
|
|
634
608
|
// show a breakdown of different object structures
|
|
635
609
|
this.breakDownSnapshotByShapes(snapshot);
|
|
636
610
|
}
|
|
637
|
-
let numOfLeakedObjects = 0;
|
|
638
|
-
let i = 0;
|
|
639
611
|
const nodeIdInPaths = new Set();
|
|
640
612
|
const paths = [];
|
|
613
|
+
let numOfLeakedObjects = 0;
|
|
614
|
+
let i = 0;
|
|
641
615
|
// analysis for each node
|
|
642
616
|
Utils_1.default.applyToNodes(leakedNodeIds, snapshot, node => {
|
|
643
617
|
if (!Config_1.default.isContinuousTest && ++i % 11 === 0) {
|
|
@@ -645,19 +619,12 @@ class MemoryAnalyst {
|
|
|
645
619
|
}
|
|
646
620
|
// BFS search for path from the leaked node to GC roots
|
|
647
621
|
const p = finder.getPathToGCRoots(snapshot, node);
|
|
648
|
-
if (!p) {
|
|
649
|
-
return;
|
|
650
|
-
}
|
|
651
|
-
if (!Utils_1.default.isInterestingPath(p)) {
|
|
622
|
+
if (!p || !Utils_1.default.isInterestingPath(p)) {
|
|
652
623
|
return;
|
|
653
624
|
}
|
|
654
625
|
++numOfLeakedObjects;
|
|
655
626
|
paths.push(p);
|
|
656
|
-
|
|
657
|
-
if (Config_1.default.isFullRun) {
|
|
658
|
-
const pathStr = Serializer_1.default.summarizePath(p, nodeIdInPaths, snapshot);
|
|
659
|
-
fs_1.default.appendFileSync(Config_1.default.exploreResultFile, `\n\n${pathStr}\n\n`, 'UTF-8');
|
|
660
|
-
}
|
|
627
|
+
this.logLeakTraceSummary(p, nodeIdInPaths, snapshot);
|
|
661
628
|
}, { reverse: true });
|
|
662
629
|
if (Config_1.default.verbose) {
|
|
663
630
|
Console_1.default.midLevel(`${numOfLeakedObjects} leaked objects`);
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
* @emails oncall+ws_labs
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
|
+
/** @internal */
|
|
10
11
|
export declare abstract class InternalValueSetter<T> {
|
|
11
12
|
fillIn(_module: T): T;
|
|
12
13
|
}
|
|
14
|
+
/** @internal */
|
|
13
15
|
export declare function setInternalValue<T>(value: T, callerFilePath: string, internalFolderName: string): T;
|
|
14
16
|
//# sourceMappingURL=InternalValueSetter.d.ts.map
|
|
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.setInternalValue = exports.InternalValueSetter = void 0;
|
|
16
16
|
const fs_1 = __importDefault(require("fs"));
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
|
+
/** @internal */
|
|
18
19
|
class InternalValueSetter {
|
|
19
20
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
21
|
fillIn(_module) {
|
|
@@ -22,6 +23,7 @@ class InternalValueSetter {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
exports.InternalValueSetter = InternalValueSetter;
|
|
26
|
+
/** @internal */
|
|
25
27
|
function setInternalValue(value, callerFilePath, internalFolderName) {
|
|
26
28
|
const callerDir = path_1.default.dirname(callerFilePath);
|
|
27
29
|
const callerFile = path_1.default.basename(callerFilePath);
|