diff --git a/packages/core/src/lib/Config.ts b/packages/core/src/lib/Config.ts index 861e0122..848492f1 100644 --- a/packages/core/src/lib/Config.ts +++ b/packages/core/src/lib/Config.ts @@ -242,6 +242,7 @@ export class MemLabConfig { maxSamplesForClustering: number; filterTraceByName: Nullable; skipBrowserCloseWait: boolean; + simplifyCodeSerialization: boolean; constructor(options: ConfigOption = {}) { // init properties, they can be configured manually @@ -375,6 +376,9 @@ export class MemLabConfig { this.filterTraceByName = null; // if true, memlab will not wait for the browser to close successfully this.skipBrowserCloseWait = false; + // if true, serialized leak trace will have a simplified representation + // for code object, which could be large and cause OOM during serualization + this.simplifyCodeSerialization = !constant.isFB; } // initialize configurable parameters diff --git a/packages/core/src/lib/Serializer.ts b/packages/core/src/lib/Serializer.ts index 2f67a701..41ebbc21 100644 --- a/packages/core/src/lib/Serializer.ts +++ b/packages/core/src/lib/Serializer.ts @@ -329,18 +329,23 @@ function JSONifyCode( options: JSONifyOptions, ): ISerializedInfo { const info = Object.create(null); + iterateSelectedEdges(node, (edge: IHeapEdge): Optional<{stop: boolean}> => { if ( edge.name_or_index === 'name_or_scope_info' && edge.toNode.name === '(function scope info)' ) { const key = 'variables with non-number values in closure scope chain'; - info[key] = JSONifyNode(edge.toNode, args, options); + info[key] = config.simplifyCodeSerialization + ? JSONifyNodeOneLevel(edge.toNode) + : JSONifyNode(edge.toNode, args, options); } else if (edge.name_or_index === 'script_or_debug_info') { info['script URL'] = edge.toNode.name; } else { const key = filterJSONPropName(edge.name_or_index); - info[key] = JSONifyNode(edge.toNode, args, options); + info[key] = config.simplifyCodeSerialization + ? JSONifyNodeOneLevel(edge.toNode) + : JSONifyNode(edge.toNode, args, options); } return null; });