@memlab/heap-analysis 1.0.32 → 1.0.33

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.
@@ -51,6 +51,7 @@ type PrintNodeOption = {
51
51
  printReferences?: boolean;
52
52
  };
53
53
  declare function printNodeListInTerminal(nodeList: IHeapNode[], options?: AnyOptions & PrintNodeOption): void;
54
+ declare function printNodeInTerminal(node: IHeapNode): void;
54
55
  declare function printReferencesInTerminal(edgeList: IHeapEdge[], options?: AnyOptions & PrintNodeOption): void;
55
56
  declare function printReferrersInTerminal(edgeList: IHeapEdge[], options?: AnyOptions & PrintNodeOption): void;
56
57
  declare function getObjectOutgoingEdgeCount(node: IHeapNode): number;
@@ -360,6 +361,7 @@ declare const _default: {
360
361
  printNodeListInTerminal: typeof printNodeListInTerminal;
361
362
  printReferencesInTerminal: typeof printReferencesInTerminal;
362
363
  printReferrersInTerminal: typeof printReferrersInTerminal;
364
+ printNodeInTerminal: typeof printNodeInTerminal;
363
365
  snapshotMapReduce: typeof snapshotMapReduce;
364
366
  takeNodeFullHeap: typeof takeNodeFullHeap;
365
367
  };
@@ -1 +1 @@
1
- {"version":3,"file":"PluginUtils.d.ts","sourceRoot":"","sources":["../src/PluginUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PluginUtils.d.ts","sourceRoot":"","sources":["../src/PluginUtils.ts"],"names":[],"mappings":"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"}
@@ -95,6 +95,40 @@ function filterOutDominators(nodeList) {
95
95
  }
96
96
  return nodeList.filter(node => candidateIdSet.has(node.id));
97
97
  }
98
+ // Note: be cautious when using printRef = true, it may cause infinite loop
99
+ function getNodeRecord(node, printRef = false) {
100
+ const refs = node.references.slice(0, MAX_NUM_OF_EDGES_TO_PRINT);
101
+ return {
102
+ id: node.id,
103
+ name: node.name,
104
+ type: node.type,
105
+ selfsize: node.self_size,
106
+ retainedSize: node.retainedSize,
107
+ traceNodeId: node.trace_node_id,
108
+ nodeIndex: node.nodeIndex,
109
+ references: printRef
110
+ ? refs.map(edge => getEdgeRecord(edge))
111
+ : refs.map(edge => ({
112
+ name: edge.name_or_index.toString(),
113
+ toNode: edge.toNode.id,
114
+ })),
115
+ referrers: node.referrers.slice(0, MAX_NUM_OF_EDGES_TO_PRINT).map(edge => ({
116
+ name: edge.name_or_index.toString(),
117
+ fromNode: edge.fromNode.id,
118
+ })),
119
+ };
120
+ }
121
+ function getEdgeRecord(edge) {
122
+ return {
123
+ nameOrIndex: edge.name_or_index,
124
+ type: edge.type,
125
+ edgeIndex: edge.edgeIndex,
126
+ toNode: getNodeRecord(edge.toNode),
127
+ fromNode: getNodeRecord(edge.fromNode),
128
+ };
129
+ }
130
+ // Note: be cautious when setting printReferences to true,
131
+ // it may cause infinite loop
98
132
  function printNodeListInTerminal(nodeList, options = {}) {
99
133
  const dot = chalk_1.default.grey('· ');
100
134
  const indent = options.indent || '';
@@ -102,6 +136,12 @@ function printNodeListInTerminal(nodeList, options = {}) {
102
136
  if (!options.printAll) {
103
137
  nodeList = filterOutDominators(nodeList);
104
138
  }
139
+ if (core_1.config.outputFormat === core_1.OutputFormat.Json) {
140
+ const jsonNodes = nodeList.map(node => getNodeRecord(node, printRef));
141
+ core_2.info.writeOutput(JSON.stringify(jsonNodes));
142
+ core_2.info.writeOutput('\n');
143
+ return;
144
+ }
105
145
  for (const node of nodeList) {
106
146
  const nodeInfo = getHeapObjectString(node);
107
147
  core_2.info.topLevel(`${indent}${dot}${nodeInfo}`);
@@ -110,6 +150,11 @@ function printNodeListInTerminal(nodeList, options = {}) {
110
150
  }
111
151
  }
112
152
  }
153
+ function printNodeInTerminal(node) {
154
+ const nodeRecord = getNodeRecord(node);
155
+ core_2.info.writeOutput(JSON.stringify(nodeRecord));
156
+ core_2.info.writeOutput('\n');
157
+ }
113
158
  function isNumeric(v) {
114
159
  if (typeof v === 'number') {
115
160
  return true;
@@ -171,6 +216,11 @@ function getReferenceString(edge) {
171
216
  return ` --${edgeName}--> ${objectInfo}`;
172
217
  }
173
218
  function printReferencesInTerminal(edgeList, options = {}) {
219
+ if (core_1.config.outputFormat === core_1.OutputFormat.Json) {
220
+ const jsonEdges = edgeList.map(edge => getEdgeRecord(edge));
221
+ core_2.info.writeOutput(JSON.stringify(jsonEdges));
222
+ core_2.info.writeOutput('\n');
223
+ }
174
224
  const dot = chalk_1.default.grey('· ');
175
225
  const indent = options.indent || '';
176
226
  let n = 0;
@@ -654,6 +704,7 @@ exports.default = {
654
704
  printNodeListInTerminal,
655
705
  printReferencesInTerminal,
656
706
  printReferrersInTerminal,
707
+ printNodeInTerminal,
657
708
  snapshotMapReduce,
658
709
  takeNodeFullHeap,
659
710
  };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall web_perf_infra
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class HeapAnalysisOutputOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ getExampleValues(): string[];
17
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
18
+ private static parseOutputFormat;
19
+ }
20
+ //# sourceMappingURL=HeapAnalysisOutputOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeapAnalysisOutputOption.d.ts","sourceRoot":"","sources":["../../src/options/HeapAnalysisOutputOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,EAAC,YAAY,EAAsB,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAExC,MAAM,CAAC,OAAO,OAAO,wBAAyB,SAAQ,UAAU;IAC9D,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,IAAI,MAAM,EAAE;IAItB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IASlE,OAAO,CAAC,MAAM,CAAC,iBAAiB;CAWjC"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @format
9
+ * @oncall web_perf_infra
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ const core_1 = require("@memlab/core");
22
+ const core_2 = require("@memlab/core");
23
+ class HeapAnalysisOutputOption extends core_2.BaseOption {
24
+ getOptionName() {
25
+ return 'output';
26
+ }
27
+ getDescription() {
28
+ return 'specify output format of the analysis (defaults to text)';
29
+ }
30
+ getExampleValues() {
31
+ return ['text', 'json'];
32
+ }
33
+ parse(config, args) {
34
+ var _a;
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ const name = this.getOptionName();
37
+ const format = (_a = `${args[name]}`) !== null && _a !== void 0 ? _a : 'text';
38
+ config.outputFormat = HeapAnalysisOutputOption.parseOutputFormat(format);
39
+ if (config.outputFormat === core_1.OutputFormat.Json) {
40
+ config.isContinuousTest = true;
41
+ }
42
+ });
43
+ }
44
+ static parseOutputFormat(s) {
45
+ switch (s.toLowerCase()) {
46
+ case 'text':
47
+ return core_1.OutputFormat.Text;
48
+ case 'json':
49
+ return core_1.OutputFormat.Json;
50
+ default:
51
+ core_1.utils.haltOrThrow('Invalid output format, valid output: text, json');
52
+ return core_1.OutputFormat.Text;
53
+ }
54
+ }
55
+ }
56
+ exports.default = HeapAnalysisOutputOption;
@@ -23,5 +23,6 @@ export default class CollectionsHoldingStaleAnalysis extends BaseAnalysis {
23
23
  process(options: HeapAnalysisOptions): Promise<void>;
24
24
  private getCollectionsWithStaleValues;
25
25
  private print;
26
+ private printJson;
26
27
  }
27
28
  //# sourceMappingURL=CollectionsHoldingStaleAnalysis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CollectionsHoldingStaleAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/CollectionsHoldingStaleAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,qBAAqB,EAAE,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAG/E,OAAO,EAAc,UAAU,EAAC,MAAM,cAAc,CAAC;AACrD,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAgD3C,MAAM,CAAC,OAAO,OAAO,+BAAgC,SAAQ,YAAY;IAChE,cAAc,IAAI,MAAM;IAI/B,gBAAgB;IACT,cAAc,IAAI,MAAM;IAI/B,gBAAgB;IAChB,UAAU,IAAI,UAAU,EAAE;IAI1B,gBAAgB;IACH,2BAA2B,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,CAAC;IAQjC,OAAO,CAAC,qBAAqB,CAO1B;IAEH,gBAAgB;IACV,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1D,OAAO,CAAC,6BAA6B;IAoBrC,OAAO,CAAC,KAAK;CAgCd"}
1
+ {"version":3,"file":"CollectionsHoldingStaleAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/CollectionsHoldingStaleAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,qBAAqB,EAAE,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAG/E,OAAO,EAAc,UAAU,EAAuB,MAAM,cAAc,CAAC;AAC3E,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAmD3C,MAAM,CAAC,OAAO,OAAO,+BAAgC,SAAQ,YAAY;IAChE,cAAc,IAAI,MAAM;IAI/B,gBAAgB;IACT,cAAc,IAAI,MAAM;IAI/B,gBAAgB;IAChB,UAAU,IAAI,UAAU,EAAE;IAI1B,gBAAgB;IACH,2BAA2B,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,CAAC;IAQjC,OAAO,CAAC,qBAAqB,CAO1B;IAEH,gBAAgB;IACV,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAU1D,OAAO,CAAC,6BAA6B;IAoBrC,OAAO,CAAC,KAAK;IAiCb,OAAO,CAAC,SAAS;CAelB"}
@@ -26,6 +26,8 @@ const BaseAnalysis_1 = __importDefault(require("../BaseAnalysis"));
26
26
  const PluginUtils_1 = __importDefault(require("../PluginUtils"));
27
27
  const chalk_1 = __importDefault(require("chalk"));
28
28
  const HeapAnalysisSnapshotFileOption_1 = __importDefault(require("../options/HeapAnalysisSnapshotFileOption"));
29
+ const HeapAnalysisOutputOption_1 = __importDefault(require("../options/HeapAnalysisOutputOption"));
30
+ const MAX_COLLECTION_STAT_ITEMS = 20;
29
31
  function initCollectionStat(collection) {
30
32
  return {
31
33
  collection,
@@ -75,7 +77,7 @@ class CollectionsHoldingStaleAnalysis extends BaseAnalysis_1.default {
75
77
  }
76
78
  /** @internal */
77
79
  getOptions() {
78
- return [new HeapAnalysisSnapshotFileOption_1.default()];
80
+ return [new HeapAnalysisSnapshotFileOption_1.default(), new HeapAnalysisOutputOption_1.default()];
79
81
  }
80
82
  /** @internal */
81
83
  analyzeSnapshotsInDirectory(directory) {
@@ -90,7 +92,12 @@ class CollectionsHoldingStaleAnalysis extends BaseAnalysis_1.default {
90
92
  return __awaiter(this, void 0, void 0, function* () {
91
93
  const snapshot = yield PluginUtils_1.default.loadHeapSnapshot(options);
92
94
  const collectionsStat = this.getCollectionsWithStaleValues(snapshot);
93
- this.print(collectionsStat);
95
+ if (core_1.config.outputFormat === core_1.OutputFormat.Json) {
96
+ this.printJson(collectionsStat);
97
+ }
98
+ else {
99
+ this.print(collectionsStat);
100
+ }
94
101
  });
95
102
  }
96
103
  getCollectionsWithStaleValues(snapshot) {
@@ -119,7 +126,7 @@ class CollectionsHoldingStaleAnalysis extends BaseAnalysis_1.default {
119
126
  core_1.info.topLevel(head('\nCollections holding stale objects:'));
120
127
  }
121
128
  collections.sort((c1, c2) => c2.staleRetainedSize - c1.staleRetainedSize);
122
- collections = collections.slice(0, 20);
129
+ collections = collections.slice(0, MAX_COLLECTION_STAT_ITEMS);
123
130
  for (const stat of collections) {
124
131
  const collection = stat.collection;
125
132
  const collectionSize = core_1.utils.getReadableBytes(collection.retainedSize);
@@ -139,5 +146,19 @@ class CollectionsHoldingStaleAnalysis extends BaseAnalysis_1.default {
139
146
  core_1.info.topLevel(` ${childrenDesc}`);
140
147
  }
141
148
  }
149
+ printJson(collections) {
150
+ collections.sort((c1, c2) => c2.staleRetainedSize - c1.staleRetainedSize);
151
+ const output = collections
152
+ .slice(0, MAX_COLLECTION_STAT_ITEMS)
153
+ .map(stat => ({
154
+ id: stat.collection.id,
155
+ size: core_1.utils.getReadableBytes(stat.collection.retainedSize),
156
+ childrenSize: stat.childrenSize,
157
+ staleChildrenSize: stat.staleChildren.length,
158
+ staleChildrenIds: stat.staleChildren.map(node => node.id),
159
+ }));
160
+ core_1.info.writeOutput(JSON.stringify(output));
161
+ core_1.info.writeOutput('\n');
162
+ }
142
163
  }
143
164
  exports.default = CollectionsHoldingStaleAnalysis;
@@ -18,6 +18,7 @@ declare class GlobalVariableAnalysis extends BaseAnalysis {
18
18
  getOptions(): BaseOption[];
19
19
  /** @internal */
20
20
  process(options: HeapAnalysisOptions): Promise<void>;
21
+ private print;
21
22
  /** @internal */
22
23
  analyzeSnapshotsInDirectory(directory: string): Promise<AnalyzeSnapshotResult>;
23
24
  /** @internal */
@@ -1 +1 @@
1
- {"version":3,"file":"ObjectContentAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/ObjectContentAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAC,qBAAqB,EAAE,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAG/E,OAAO,EAAC,UAAU,EAAsB,MAAM,cAAc,CAAC;AAG7D,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAG3C,cAAM,sBAAuB,SAAQ,YAAY;IAC/C,cAAc,IAAI,MAAM;IAIxB,gBAAgB;IAChB,cAAc,IAAI,MAAM;IAIxB,gBAAgB;IAChB,UAAU,IAAI,UAAU,EAAE;IAI1B,gBAAgB;IACV,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuC1D,gBAAgB;IACH,2BAA2B,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,CAAC;IAQjC,gBAAgB;IAChB,OAAO,CAAC,mBAAmB;IAY3B,gBAAgB;IAChB,OAAO,CAAC,sBAAsB;CAW/B;AAED,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"ObjectContentAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/ObjectContentAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAC,qBAAqB,EAAE,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAG/E,OAAO,EAAC,UAAU,EAAoC,MAAM,cAAc,CAAC;AAG3E,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAI3C,cAAM,sBAAuB,SAAQ,YAAY;IAC/C,cAAc,IAAI,MAAM;IAIxB,gBAAgB;IAChB,cAAc,IAAI,MAAM;IAIxB,gBAAgB;IAChB,UAAU,IAAI,UAAU,EAAE;IAI1B,gBAAgB;IACV,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB1D,OAAO,CAAC,KAAK;IA8Bb,gBAAgB;IACH,2BAA2B,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,CAAC;IAQjC,gBAAgB;IAChB,OAAO,CAAC,mBAAmB;IAY3B,gBAAgB;IAChB,OAAO,CAAC,sBAAsB;CAW/B;AAED,eAAe,sBAAsB,CAAC"}
@@ -27,6 +27,7 @@ const HeapAnalysisNodeIdOption_1 = __importDefault(require("../options/HeapAnaly
27
27
  const HeapAnalysisSnapshotFileOption_1 = __importDefault(require("../options/HeapAnalysisSnapshotFileOption"));
28
28
  const BaseAnalysis_1 = __importDefault(require("../BaseAnalysis"));
29
29
  const PluginUtils_1 = __importDefault(require("../PluginUtils"));
30
+ const HeapAnalysisOutputOption_1 = __importDefault(require("../options/HeapAnalysisOutputOption"));
30
31
  class GlobalVariableAnalysis extends BaseAnalysis_1.default {
31
32
  getCommandName() {
32
33
  return 'object';
@@ -37,7 +38,7 @@ class GlobalVariableAnalysis extends BaseAnalysis_1.default {
37
38
  }
38
39
  /** @internal */
39
40
  getOptions() {
40
- return [new HeapAnalysisSnapshotFileOption_1.default(), new HeapAnalysisNodeIdOption_1.default()];
41
+ return [new HeapAnalysisSnapshotFileOption_1.default(), new HeapAnalysisNodeIdOption_1.default(), new HeapAnalysisOutputOption_1.default()];
41
42
  }
42
43
  /** @internal */
43
44
  process(options) {
@@ -50,34 +51,41 @@ class GlobalVariableAnalysis extends BaseAnalysis_1.default {
50
51
  core_1.info.lowLevel(`Specify an object by --node-id`);
51
52
  return;
52
53
  }
53
- // print object info
54
- const id = chalk_1.default.grey(`@${node.id}`);
55
- core_1.info.topLevel(`Heap node (${node.type}) ${id}`);
56
- const name = chalk_1.default.grey(`${node.name}`);
57
- core_1.info.topLevel(` name: ${name}`);
58
- const numReferences = chalk_1.default.grey(`${node.edge_count}`);
59
- core_1.info.topLevel(` # of references: ${numReferences}`);
60
- const numReferrers = chalk_1.default.grey(`${node.referrers.length}`);
61
- core_1.info.topLevel(` # of referrers: ${numReferrers}`);
62
- const selfSize = chalk_1.default.grey(`${node.self_size}`);
63
- core_1.info.topLevel(` shallow size: ${selfSize}`);
64
- const retainedSize = chalk_1.default.grey(`${node.retainedSize}`);
65
- core_1.info.topLevel(` retained size: ${retainedSize}`);
66
- const dominatorNode = node.dominatorNode;
67
- if (dominatorNode) {
68
- const dominatorNodeId = chalk_1.default.grey(`@${dominatorNode.id}`);
69
- core_1.info.topLevel(` dominator node: ${dominatorNodeId}`);
54
+ if (core_1.config.outputFormat === core_1.OutputFormat.Json) {
55
+ PluginUtils_1.default.printNodeInTerminal(node);
56
+ }
57
+ else {
58
+ this.print(node, snapshot);
70
59
  }
71
- // print object references
72
- core_1.info.topLevel('\n' + chalk_1.default.bold('REFERENCES:'));
73
- let list = this.getObjectProperties(snapshot, node);
74
- PluginUtils_1.default.printReferencesInTerminal(list);
75
- core_1.info.topLevel('\n' + chalk_1.default.bold('REFERRERS:'));
76
- // print object referrers
77
- list = this.getObjectReferrerEdges(snapshot, node);
78
- PluginUtils_1.default.printReferrersInTerminal(list);
79
60
  });
80
61
  }
62
+ print(node, snapshot) {
63
+ const id = chalk_1.default.grey(`@${node.id}`);
64
+ core_1.info.topLevel(`Heap node (${node.type}) ${id}`);
65
+ const name = chalk_1.default.grey(`${node.name}`);
66
+ core_1.info.topLevel(` name: ${name}`);
67
+ const numReferences = chalk_1.default.grey(`${node.edge_count}`);
68
+ core_1.info.topLevel(` # of references: ${numReferences}`);
69
+ const numReferrers = chalk_1.default.grey(`${node.referrers.length}`);
70
+ core_1.info.topLevel(` # of referrers: ${numReferrers}`);
71
+ const selfSize = chalk_1.default.grey(`${node.self_size}`);
72
+ core_1.info.topLevel(` shallow size: ${selfSize}`);
73
+ const retainedSize = chalk_1.default.grey(`${node.retainedSize}`);
74
+ core_1.info.topLevel(` retained size: ${retainedSize}`);
75
+ const dominatorNode = node.dominatorNode;
76
+ if (dominatorNode) {
77
+ const dominatorNodeId = chalk_1.default.grey(`@${dominatorNode.id}`);
78
+ core_1.info.topLevel(` dominator node: ${dominatorNodeId}`);
79
+ }
80
+ // print object references
81
+ core_1.info.topLevel('\n' + chalk_1.default.bold('REFERENCES:'));
82
+ let list = this.getObjectProperties(snapshot, node);
83
+ PluginUtils_1.default.printReferencesInTerminal(list);
84
+ core_1.info.topLevel('\n' + chalk_1.default.bold('REFERRERS:'));
85
+ // print object referrers
86
+ list = this.getObjectReferrerEdges(snapshot, node);
87
+ PluginUtils_1.default.printReferrersInTerminal(list);
88
+ }
81
89
  /** @internal */
82
90
  analyzeSnapshotsInDirectory(directory) {
83
91
  return __awaiter(this, void 0, void 0, function* () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memlab/heap-analysis",
3
- "version": "1.0.32",
3
+ "version": "1.0.33",
4
4
  "license": "MIT",
5
5
  "description": "heap analysis plugins for memlab",
6
6
  "author": "Liang Gong <lgong@fb.com>",
@@ -20,8 +20,8 @@
20
20
  "LICENSE"
21
21
  ],
22
22
  "dependencies": {
23
- "@memlab/core": "^1.1.35",
24
- "@memlab/e2e": "^1.0.35",
23
+ "@memlab/core": "^1.1.36",
24
+ "@memlab/e2e": "^1.0.36",
25
25
  "ansi": "^0.3.1",
26
26
  "babar": "^0.2.0",
27
27
  "chalk": "^4.0.0",