@memlab/core 1.0.6 → 1.1.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 +17 -0
- package/dist/index.js +17 -0
- package/dist/lib/Config.d.ts +6 -2
- package/dist/lib/Config.js +13 -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 +363 -6
- package/dist/lib/Types.js +1 -0
- 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;
|
|
@@ -137,6 +139,7 @@ export declare class MemLabConfig {
|
|
|
137
139
|
waitAfterOperation: number;
|
|
138
140
|
waitAfterScrolling: number;
|
|
139
141
|
waitAfterTyping: number;
|
|
142
|
+
waitForNetworkInDefaultScenario: number;
|
|
140
143
|
stressTestRepeat: number;
|
|
141
144
|
avoidLeakWithoutDetachedElements: boolean;
|
|
142
145
|
hideBrowserLeak: boolean;
|
|
@@ -165,6 +168,7 @@ export declare class MemLabConfig {
|
|
|
165
168
|
nodeIgnoreSetInShape: Set<string>;
|
|
166
169
|
oversizeObjectAsLeak: boolean;
|
|
167
170
|
oversizeThreshold: number;
|
|
171
|
+
clusterRetainedSizeThreshold: number;
|
|
168
172
|
_isFullRun: boolean;
|
|
169
173
|
_scenario: Optional<IScenario>;
|
|
170
174
|
externalLeakFilter?: Optional<ILeakFilter>;
|
|
@@ -199,8 +203,8 @@ export declare class MemLabConfig {
|
|
|
199
203
|
enableXvfb(display: string): void;
|
|
200
204
|
disableXvfb(): void;
|
|
201
205
|
}
|
|
202
|
-
/** @
|
|
206
|
+
/** @internal */
|
|
203
207
|
declare const config: MemLabConfig;
|
|
204
|
-
/** @
|
|
208
|
+
/** @internal */
|
|
205
209
|
export default config;
|
|
206
210
|
//# 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: [
|
|
@@ -187,6 +192,8 @@ class MemLabConfig {
|
|
|
187
192
|
this.waitAfterScrolling = 5000;
|
|
188
193
|
// extra delay after typing
|
|
189
194
|
this.waitAfterTyping = 1000;
|
|
195
|
+
// page load checker: default wait for network idle in scenario test
|
|
196
|
+
this.waitForNetworkInDefaultScenario = 10000;
|
|
190
197
|
// default repeat for stress testing
|
|
191
198
|
this.stressTestRepeat = 5;
|
|
192
199
|
// only show leaks with detached HTML elements
|
|
@@ -237,6 +244,7 @@ class MemLabConfig {
|
|
|
237
244
|
this.nodeNameGreyList = new Set([
|
|
238
245
|
'InternalNode',
|
|
239
246
|
'Pending activities',
|
|
247
|
+
'StyleEngine',
|
|
240
248
|
...Constant_1.default.V8SyntheticRoots,
|
|
241
249
|
]);
|
|
242
250
|
// edge names less preferable in trace finding
|
|
@@ -264,6 +272,9 @@ class MemLabConfig {
|
|
|
264
272
|
this.oversizeObjectAsLeak = false;
|
|
265
273
|
// if larger than this threshold, consider as memory leak
|
|
266
274
|
this.oversizeThreshold = 0;
|
|
275
|
+
// only report leak clusters with aggregated retained size
|
|
276
|
+
// bigger than this threshold
|
|
277
|
+
this.clusterRetainedSizeThreshold = 0;
|
|
267
278
|
// initialize file and directory paths
|
|
268
279
|
FileManager_1.default.initDirs(this, options);
|
|
269
280
|
}
|
|
@@ -422,8 +433,8 @@ class MemLabConfig {
|
|
|
422
433
|
}
|
|
423
434
|
}
|
|
424
435
|
exports.MemLabConfig = MemLabConfig;
|
|
425
|
-
/** @
|
|
436
|
+
/** @internal */
|
|
426
437
|
const config = MemLabConfig.getInstance();
|
|
427
438
|
(0, InternalValueSetter_1.setInternalValue)(config, __filename, Constant_1.default.internalDir);
|
|
428
|
-
/** @
|
|
439
|
+
/** @internal */
|
|
429
440
|
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);
|