@memlab/mcp-server 2.1.1 → 2.3.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.
Files changed (162) hide show
  1. package/README.md +73 -3
  2. package/dist/analysis-budget.d.ts +71 -0
  3. package/dist/analysis-budget.d.ts.map +1 -0
  4. package/dist/analysis-budget.js +118 -0
  5. package/dist/analysis-budget.js.map +1 -0
  6. package/dist/guardrail.d.ts +24 -0
  7. package/dist/guardrail.d.ts.map +1 -0
  8. package/dist/guardrail.js +65 -0
  9. package/dist/guardrail.js.map +1 -0
  10. package/dist/heap-state.d.ts +46 -1
  11. package/dist/heap-state.d.ts.map +1 -1
  12. package/dist/heap-state.js +142 -10
  13. package/dist/heap-state.js.map +1 -1
  14. package/dist/index.js +36 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/tools/array-group-by.d.ts +12 -0
  17. package/dist/tools/array-group-by.d.ts.map +1 -0
  18. package/dist/tools/array-group-by.js +191 -0
  19. package/dist/tools/array-group-by.js.map +1 -0
  20. package/dist/tools/auto-investigate.d.ts.map +1 -1
  21. package/dist/tools/auto-investigate.js +999 -37
  22. package/dist/tools/auto-investigate.js.map +1 -1
  23. package/dist/tools/cache-analysis.d.ts.map +1 -1
  24. package/dist/tools/cache-analysis.js +438 -21
  25. package/dist/tools/cache-analysis.js.map +1 -1
  26. package/dist/tools/check-health.d.ts.map +1 -1
  27. package/dist/tools/check-health.js +261 -1
  28. package/dist/tools/check-health.js.map +1 -1
  29. package/dist/tools/class-histogram.d.ts.map +1 -1
  30. package/dist/tools/class-histogram.js +142 -33
  31. package/dist/tools/class-histogram.js.map +1 -1
  32. package/dist/tools/closure-inspection.d.ts.map +1 -1
  33. package/dist/tools/closure-inspection.js +238 -25
  34. package/dist/tools/closure-inspection.js.map +1 -1
  35. package/dist/tools/detached-dom.d.ts.map +1 -1
  36. package/dist/tools/detached-dom.js +25 -3
  37. package/dist/tools/detached-dom.js.map +1 -1
  38. package/dist/tools/dev-artifacts.d.ts +33 -0
  39. package/dist/tools/dev-artifacts.d.ts.map +1 -0
  40. package/dist/tools/dev-artifacts.js +165 -0
  41. package/dist/tools/dev-artifacts.js.map +1 -0
  42. package/dist/tools/diff-snapshots.d.ts.map +1 -1
  43. package/dist/tools/diff-snapshots.js +113 -18
  44. package/dist/tools/diff-snapshots.js.map +1 -1
  45. package/dist/tools/duplicated-strings.d.ts.map +1 -1
  46. package/dist/tools/duplicated-strings.js +74 -12
  47. package/dist/tools/duplicated-strings.js.map +1 -1
  48. package/dist/tools/eval.d.ts.map +1 -1
  49. package/dist/tools/eval.js +189 -10
  50. package/dist/tools/eval.js.map +1 -1
  51. package/dist/tools/event-listener-leaks.d.ts.map +1 -1
  52. package/dist/tools/event-listener-leaks.js +235 -13
  53. package/dist/tools/event-listener-leaks.js.map +1 -1
  54. package/dist/tools/event-registry.d.ts +12 -0
  55. package/dist/tools/event-registry.d.ts.map +1 -0
  56. package/dist/tools/event-registry.js +183 -0
  57. package/dist/tools/event-registry.js.map +1 -0
  58. package/dist/tools/find-by-property.d.ts.map +1 -1
  59. package/dist/tools/find-by-property.js +113 -31
  60. package/dist/tools/find-by-property.js.map +1 -1
  61. package/dist/tools/find-by-shape.d.ts +12 -0
  62. package/dist/tools/find-by-shape.d.ts.map +1 -0
  63. package/dist/tools/find-by-shape.js +178 -0
  64. package/dist/tools/find-by-shape.js.map +1 -0
  65. package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
  66. package/dist/tools/find-nodes-by-class.js +50 -6
  67. package/dist/tools/find-nodes-by-class.js.map +1 -1
  68. package/dist/tools/for-each.d.ts.map +1 -1
  69. package/dist/tools/for-each.js +1 -1
  70. package/dist/tools/for-each.js.map +1 -1
  71. package/dist/tools/get-node.d.ts.map +1 -1
  72. package/dist/tools/get-node.js +6 -0
  73. package/dist/tools/get-node.js.map +1 -1
  74. package/dist/tools/get-string.d.ts +12 -0
  75. package/dist/tools/get-string.d.ts.map +1 -0
  76. package/dist/tools/get-string.js +223 -0
  77. package/dist/tools/get-string.js.map +1 -0
  78. package/dist/tools/get-value.d.ts +12 -0
  79. package/dist/tools/get-value.d.ts.map +1 -0
  80. package/dist/tools/get-value.js +152 -0
  81. package/dist/tools/get-value.js.map +1 -0
  82. package/dist/tools/global-variables.d.ts.map +1 -1
  83. package/dist/tools/global-variables.js +54 -34
  84. package/dist/tools/global-variables.js.map +1 -1
  85. package/dist/tools/growth-signals.d.ts +12 -0
  86. package/dist/tools/growth-signals.d.ts.map +1 -0
  87. package/dist/tools/growth-signals.js +211 -0
  88. package/dist/tools/growth-signals.js.map +1 -0
  89. package/dist/tools/intern-opportunities.d.ts +12 -0
  90. package/dist/tools/intern-opportunities.d.ts.map +1 -0
  91. package/dist/tools/intern-opportunities.js +289 -0
  92. package/dist/tools/intern-opportunities.js.map +1 -0
  93. package/dist/tools/load-snapshot.d.ts +10 -0
  94. package/dist/tools/load-snapshot.d.ts.map +1 -1
  95. package/dist/tools/load-snapshot.js +152 -15
  96. package/dist/tools/load-snapshot.js.map +1 -1
  97. package/dist/tools/object-cost-breakdown.d.ts +12 -0
  98. package/dist/tools/object-cost-breakdown.d.ts.map +1 -0
  99. package/dist/tools/object-cost-breakdown.js +439 -0
  100. package/dist/tools/object-cost-breakdown.js.map +1 -0
  101. package/dist/tools/object-shape.d.ts.map +1 -1
  102. package/dist/tools/object-shape.js +95 -2
  103. package/dist/tools/object-shape.js.map +1 -1
  104. package/dist/tools/pinch-points.d.ts.map +1 -1
  105. package/dist/tools/pinch-points.js +9 -9
  106. package/dist/tools/pinch-points.js.map +1 -1
  107. package/dist/tools/property-distribution.d.ts +12 -0
  108. package/dist/tools/property-distribution.d.ts.map +1 -0
  109. package/dist/tools/property-distribution.js +168 -0
  110. package/dist/tools/property-distribution.js.map +1 -0
  111. package/dist/tools/quick-diagnosis.d.ts.map +1 -1
  112. package/dist/tools/quick-diagnosis.js +56 -19
  113. package/dist/tools/quick-diagnosis.js.map +1 -1
  114. package/dist/tools/retainer-summary.d.ts.map +1 -1
  115. package/dist/tools/retainer-summary.js +90 -5
  116. package/dist/tools/retainer-summary.js.map +1 -1
  117. package/dist/tools/retainer-trace.d.ts.map +1 -1
  118. package/dist/tools/retainer-trace.js +74 -22
  119. package/dist/tools/retainer-trace.js.map +1 -1
  120. package/dist/tools/search-nodes.d.ts.map +1 -1
  121. package/dist/tools/search-nodes.js +10 -3
  122. package/dist/tools/search-nodes.js.map +1 -1
  123. package/dist/tools/search-strings.d.ts +12 -0
  124. package/dist/tools/search-strings.d.ts.map +1 -0
  125. package/dist/tools/search-strings.js +182 -0
  126. package/dist/tools/search-strings.js.map +1 -0
  127. package/dist/tools/sequence-analysis.d.ts +12 -0
  128. package/dist/tools/sequence-analysis.d.ts.map +1 -0
  129. package/dist/tools/sequence-analysis.js +234 -0
  130. package/dist/tools/sequence-analysis.js.map +1 -0
  131. package/dist/tools/server-status.d.ts +12 -0
  132. package/dist/tools/server-status.d.ts.map +1 -0
  133. package/dist/tools/server-status.js +41 -0
  134. package/dist/tools/server-status.js.map +1 -0
  135. package/dist/tools/shape-histogram.d.ts.map +1 -1
  136. package/dist/tools/shape-histogram.js +61 -16
  137. package/dist/tools/shape-histogram.js.map +1 -1
  138. package/dist/tools/sliced-strings.d.ts.map +1 -1
  139. package/dist/tools/sliced-strings.js +16 -11
  140. package/dist/tools/sliced-strings.js.map +1 -1
  141. package/dist/tools/snapshot-summary.d.ts.map +1 -1
  142. package/dist/tools/snapshot-summary.js +55 -13
  143. package/dist/tools/snapshot-summary.js.map +1 -1
  144. package/dist/tools/snapshots.d.ts +12 -0
  145. package/dist/tools/snapshots.d.ts.map +1 -0
  146. package/dist/tools/snapshots.js +93 -0
  147. package/dist/tools/snapshots.js.map +1 -0
  148. package/dist/tools/stale-collections.d.ts.map +1 -1
  149. package/dist/tools/stale-collections.js +248 -7
  150. package/dist/tools/stale-collections.js.map +1 -1
  151. package/dist/tools/trace-dominators.d.ts.map +1 -1
  152. package/dist/tools/trace-dominators.js +28 -1
  153. package/dist/tools/trace-dominators.js.map +1 -1
  154. package/dist/tools/weakmap-entries.d.ts +12 -0
  155. package/dist/tools/weakmap-entries.d.ts.map +1 -0
  156. package/dist/tools/weakmap-entries.js +156 -0
  157. package/dist/tools/weakmap-entries.js.map +1 -0
  158. package/dist/utils.d.ts +81 -2
  159. package/dist/utils.d.ts.map +1 -1
  160. package/dist/utils.js +303 -35
  161. package/dist/utils.js.map +1 -1
  162. package/package.json +3 -3
@@ -18,6 +18,8 @@ export function registerCheckHealth(server) {
18
18
  let totalSize = 0;
19
19
  let totalStringSize = 0;
20
20
  let detachedCount = 0;
21
+ let stringNodeCount = 0;
22
+ let objectNodeCount = 0;
21
23
  const classCounts = new Map();
22
24
  const stringCounts = new Map();
23
25
  let largestObjId = 0;
@@ -29,6 +31,7 @@ export function registerCheckHealth(server) {
29
31
  return;
30
32
  totalSize += node.self_size;
31
33
  if (node.type === 'string') {
34
+ stringNodeCount++;
32
35
  totalStringSize += node.self_size;
33
36
  if (node.name !== 'system / SlicedString') {
34
37
  const key = node.name.length > 100 ? node.name.slice(0, 100) : node.name;
@@ -42,6 +45,9 @@ export function registerCheckHealth(server) {
42
45
  }
43
46
  }
44
47
  }
48
+ else if (node.type === 'object') {
49
+ objectNodeCount++;
50
+ }
45
51
  if ((node.type === 'object' ||
46
52
  node.type === 'closure' ||
47
53
  node.type === 'regexp') &&
@@ -230,7 +236,261 @@ export function registerCheckHealth(server) {
230
236
  next_step: `memlab_retainer_summary with class_name "${name}"`,
231
237
  });
232
238
  }
233
- // Check 8: Retained module source code
239
+ // Check 8: Meta module system accumulation (__d / require)
240
+ let moduleDescriptorCount = 0;
241
+ let moduleEntryCount = 0;
242
+ snapshot.nodes.forEach(node => {
243
+ if (node.id <= 3)
244
+ return;
245
+ if (node.type !== 'object')
246
+ return;
247
+ // Module descriptors created by __d() have a specific shape
248
+ const hasFactory = node.references.some(e => String(e.name_or_index) === 'factory' && e.type === 'property');
249
+ const hasDependencies = node.references.some(e => String(e.name_or_index) === 'dependencies' &&
250
+ e.type === 'property');
251
+ if (hasFactory && hasDependencies) {
252
+ moduleDescriptorCount++;
253
+ }
254
+ // Module entries in the require map
255
+ if (node.name === 'Object') {
256
+ const hasModule = node.references.some(e => String(e.name_or_index) === 'module' && e.type === 'property');
257
+ const hasExports = node.references.some(e => String(e.name_or_index) === 'exports' && e.type === 'property');
258
+ if (hasModule && hasExports) {
259
+ moduleEntryCount++;
260
+ }
261
+ }
262
+ });
263
+ if (moduleDescriptorCount >= 10000 || moduleEntryCount >= 10000) {
264
+ const total = moduleDescriptorCount + moduleEntryCount;
265
+ findings.push({
266
+ severity: total >= 100000 ? 'warning' : 'info',
267
+ title: `Meta module system: ${formatNumber(moduleDescriptorCount)} descriptors, ${formatNumber(moduleEntryCount)} entries`,
268
+ detail: 'Large module registries from __d()/require() indicate the entire module graph is retained in memory. Check if unused modules can be lazily loaded or their factory functions released after initialization.',
269
+ next_step: 'memlab_find_by_shape with properties ["factory", "dependencies"] to inspect module descriptors',
270
+ });
271
+ }
272
+ // Check 9: ALEA/AutoLogging event accumulation
273
+ let aleaEventCount = 0;
274
+ let aleaTotalSize = 0;
275
+ snapshot.nodes.forEach(node => {
276
+ if (node.id <= 3 || node.type !== 'object')
277
+ return;
278
+ const hasEventName = node.references.some(e => (String(e.name_or_index) === 'event' ||
279
+ String(e.name_or_index) === 'eventName' ||
280
+ String(e.name_or_index) === 'event_name') &&
281
+ e.type === 'property');
282
+ const hasLoggingData = node.references.some(e => (String(e.name_or_index) === 'extra' ||
283
+ String(e.name_or_index) === 'extraData' ||
284
+ String(e.name_or_index) === 'loggingData') &&
285
+ e.type === 'property');
286
+ if (hasEventName && hasLoggingData) {
287
+ aleaEventCount++;
288
+ aleaTotalSize += node.retainedSize;
289
+ }
290
+ });
291
+ if (aleaEventCount >= 1000) {
292
+ findings.push({
293
+ severity: aleaTotalSize >= totalSize * 0.05 ? 'warning' : 'info',
294
+ title: `${formatNumber(aleaEventCount)} AutoLogging/ALEA event objects (${formatBytes(aleaTotalSize)})`,
295
+ detail: 'Event objects with event/eventName + extra/loggingData properties are accumulating. This is a known pattern where logging events are queued but not flushed.',
296
+ next_step: 'memlab_find_by_shape with properties ["event", "extra"] to inspect event objects',
297
+ });
298
+ }
299
+ // Check 10: Relay/Flux store sizes
300
+ const storeNames = ['RelayModernStore', 'RelayStore', 'FluxStore'];
301
+ snapshot.nodes.forEach(node => {
302
+ if (node.id <= 3 || node.type !== 'object')
303
+ return;
304
+ if (!storeNames.includes(node.name))
305
+ return;
306
+ if (node.retainedSize >= 5 * 1024 * 1024) {
307
+ const pct = totalSize > 0
308
+ ? ((node.retainedSize / totalSize) * 100).toFixed(1)
309
+ : '?';
310
+ findings.push({
311
+ severity: node.retainedSize >= totalSize * 0.1 ? 'warning' : 'info',
312
+ title: `\`${node.name}\` @${node.id} retains ${formatBytes(node.retainedSize)} (${pct}% of heap)`,
313
+ detail: 'Large Relay/Flux store may indicate stale query data or missing garbage collection of normalized records.',
314
+ next_step: `memlab_dominator_subtree with node_id ${node.id} to see what the store retains`,
315
+ });
316
+ }
317
+ });
318
+ // Check 11: EventHandlerRefInternal leak pattern
319
+ // Detects refs with non-null element but null handlers — the exact
320
+ // pattern of a known memory leak where the DOM element is retained
321
+ // after handlers are removed.
322
+ let leakyHandlerRefCount = 0;
323
+ let leakyHandlerRefExampleId = 0;
324
+ let leakyHandlerRefTotalSize = 0;
325
+ snapshot.nodes.forEach(node => {
326
+ if (node.id <= 3 || node.type !== 'object')
327
+ return;
328
+ if (!node.name.includes('EventHandler') &&
329
+ !node.name.includes('HandlerRef'))
330
+ return;
331
+ let hasElement = false;
332
+ let handlersNull = false;
333
+ for (const edge of node.references) {
334
+ const eName = String(edge.name_or_index);
335
+ if ((eName === '#element' ||
336
+ eName === 'element' ||
337
+ eName === '_element') &&
338
+ edge.toNode.id > 3 &&
339
+ edge.toNode.name !== 'undefined' &&
340
+ edge.toNode.name !== 'null') {
341
+ hasElement = true;
342
+ }
343
+ if ((eName === '#handlers' ||
344
+ eName === 'handlers' ||
345
+ eName === '_handlers') &&
346
+ (edge.toNode.id <= 3 ||
347
+ edge.toNode.name === 'null' ||
348
+ edge.toNode.name === 'undefined')) {
349
+ handlersNull = true;
350
+ }
351
+ }
352
+ if (hasElement && handlersNull) {
353
+ leakyHandlerRefCount++;
354
+ leakyHandlerRefTotalSize += node.retainedSize;
355
+ if (!leakyHandlerRefExampleId)
356
+ leakyHandlerRefExampleId = node.id;
357
+ }
358
+ });
359
+ if (leakyHandlerRefCount >= 10) {
360
+ findings.push({
361
+ severity: leakyHandlerRefTotalSize >= totalSize * 0.01 ? 'warning' : 'info',
362
+ title: `${formatNumber(leakyHandlerRefCount)} EventHandlerRef(s) with element but no handlers`,
363
+ detail: `These refs retain DOM elements after their handlers were removed — a known leak pattern. Total retained: ${formatBytes(leakyHandlerRefTotalSize)}.`,
364
+ next_step: `memlab_retainer_trace with node_id ${leakyHandlerRefExampleId} to trace the retention path`,
365
+ });
366
+ }
367
+ // Check 12: String-to-object ratio (Feedback #11)
368
+ let heavyDupStringCount = 0;
369
+ for (const [, stats] of stringCounts) {
370
+ if (stats.count >= 100_000)
371
+ heavyDupStringCount++;
372
+ }
373
+ if (objectNodeCount > 0 &&
374
+ stringNodeCount / objectNodeCount > 2 &&
375
+ heavyDupStringCount > 0) {
376
+ const ratio = (stringNodeCount / objectNodeCount).toFixed(1);
377
+ findings.push({
378
+ severity: totalStringSize >= totalSize * 0.3 ? 'warning' : 'info',
379
+ title: `High string-to-object ratio: ${ratio}:1 with ${heavyDupStringCount} heavily duplicated string(s)`,
380
+ detail: `${formatNumber(stringNodeCount)} strings vs ${formatNumber(objectNodeCount)} objects. Combined with heavy duplication (>100K copies), this strongly indicates JSON.parse output without string interning.`,
381
+ next_step: 'memlab_intern_opportunities to see savings grouped by property × parent shape',
382
+ });
383
+ }
384
+ // Check 13: Async context retention patterns (Feedback #10)
385
+ if (env === 'node') {
386
+ let tcpContextLeakCount = 0;
387
+ let tcpContextExampleId = 0;
388
+ let tcpContextTotalSize = 0;
389
+ snapshot.nodes.forEach(node => {
390
+ if (node.id <= 3 || node.type !== 'object')
391
+ return;
392
+ if (node.name !== 'TCP' &&
393
+ node.name !== 'Socket' &&
394
+ !node.name.includes('TCP'))
395
+ return;
396
+ let hasResourceStore = false;
397
+ let contextRetained = 0;
398
+ for (const edge of node.references) {
399
+ const eName = String(edge.name_or_index);
400
+ if (eName === 'kResourceStore' || eName === 'resource_symbol') {
401
+ hasResourceStore = true;
402
+ contextRetained = edge.toNode.retainedSize;
403
+ break;
404
+ }
405
+ }
406
+ if (hasResourceStore && contextRetained > 1024 * 1024) {
407
+ tcpContextLeakCount++;
408
+ tcpContextTotalSize += contextRetained;
409
+ if (!tcpContextExampleId)
410
+ tcpContextExampleId = node.id;
411
+ }
412
+ });
413
+ if (tcpContextLeakCount > 0) {
414
+ findings.push({
415
+ severity: tcpContextTotalSize >= totalSize * 0.05
416
+ ? 'critical'
417
+ : 'warning',
418
+ title: `${tcpContextLeakCount} TCP connection(s) retaining AsyncLocalStorage contexts (${formatBytes(tcpContextTotalSize)})`,
419
+ detail: 'TCP sockets are holding request-scoped data via kResourceStore → afterContext chains. This is a known Next.js/Node.js pattern where unconsumed response bodies keep request contexts alive.',
420
+ next_step: `memlab_retainer_trace with node_id ${tcpContextExampleId} to see the full async context chain`,
421
+ });
422
+ }
423
+ }
424
+ // Check 14: WebSocket/TCP connection accumulation (Feedback #4)
425
+ if (env === 'node') {
426
+ const CONN_CLASSES = ['TCP', 'Socket', 'TLSSocket', 'WebSocket'];
427
+ for (const cls of CONN_CLASSES) {
428
+ const count = classCounts.get(cls) ?? 0;
429
+ if (count < 1000)
430
+ continue;
431
+ let connRetained = 0;
432
+ let connExampleId = 0;
433
+ snapshot.nodes.forEach(node => {
434
+ if (node.id <= 3 || node.type !== 'object')
435
+ return;
436
+ if (node.name !== cls)
437
+ return;
438
+ connRetained += node.retainedSize;
439
+ if (!connExampleId)
440
+ connExampleId = node.id;
441
+ });
442
+ if (connRetained > 1024 * 1024) {
443
+ findings.push({
444
+ severity: connRetained >= totalSize * 0.05 ? 'critical' : 'warning',
445
+ title: `${formatNumber(count)} \`${cls}\` instances accumulating (${formatBytes(connRetained)} retained)`,
446
+ detail: `High connection instance count suggests connections are not being properly closed or are accumulating faster than they are cleaned up.`,
447
+ next_step: `memlab_find_nodes_by_class with class_name "${cls}" to inspect representative instances, then memlab_retainer_trace to find what is keeping them alive`,
448
+ });
449
+ }
450
+ }
451
+ }
452
+ // Check 15: mysql2/Drizzle connection retention (Feedback #8, #11)
453
+ if (env === 'node') {
454
+ let mysqlConnCount = 0;
455
+ let mysqlConnRetained = 0;
456
+ let mysqlConnExampleId = 0;
457
+ snapshot.nodes.forEach(node => {
458
+ if (node.id <= 3 || node.type !== 'object')
459
+ return;
460
+ if (node.name !== 'Connection' &&
461
+ node.name !== 'PoolConnection' &&
462
+ node.name !== 'PromiseConnection')
463
+ return;
464
+ let hasProtocol = false;
465
+ let hasConfig = false;
466
+ for (const edge of node.references) {
467
+ const eName = String(edge.name_or_index);
468
+ if (eName === '_protocol' || eName === 'stream') {
469
+ hasProtocol = true;
470
+ }
471
+ if (eName === 'config' || eName === 'connectionConfig') {
472
+ hasConfig = true;
473
+ }
474
+ }
475
+ if (hasProtocol && hasConfig) {
476
+ mysqlConnCount++;
477
+ mysqlConnRetained += node.retainedSize;
478
+ if (!mysqlConnExampleId)
479
+ mysqlConnExampleId = node.id;
480
+ }
481
+ });
482
+ if (mysqlConnCount > 0 && mysqlConnRetained > 1024 * 1024) {
483
+ findings.push({
484
+ severity: mysqlConnRetained >= totalSize * 0.05 ? 'critical' : 'warning',
485
+ title: `${mysqlConnCount} mysql2 Connection(s) retaining ${formatBytes(mysqlConnRetained)}`,
486
+ detail: 'mysql2 Connection objects are holding query results, protocol buffers, or error handler closure chains. ' +
487
+ 'This is common when connections stay open in a pool without an idle timeout.',
488
+ next_step: `memlab_retainer_trace with node_id ${mysqlConnExampleId} to trace the retention chain. ` +
489
+ 'Fix: set pool `idleTimeout` (e.g., 60000ms) to release idle connections, and ensure query results are not captured in long-lived closures',
490
+ });
491
+ }
492
+ }
493
+ // Check 16: Retained module source code
234
494
  let moduleSourceSize = 0;
235
495
  let moduleSourceCount = 0;
236
496
  snapshot.nodes.forEach(node => {
@@ -1 +1 @@
1
- {"version":3,"file":"check-health.js","sourceRoot":"","sources":["../../src/tools/check-health.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check-health.js","sourceRoot":"","sources":["../../src/tools/check-health.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"class-histogram.d.ts","sourceRoot":"","sources":["../../src/tools/class-histogram.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAevE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgM9D"}
1
+ {"version":3,"file":"class-histogram.d.ts","sourceRoot":"","sources":["../../src/tools/class-histogram.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAkBvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgU9D"}
@@ -9,11 +9,15 @@
9
9
  */
10
10
  import { z } from 'zod';
11
11
  import memlabCore from '@memlab/core';
12
- const { utils, NumericSet } = memlabCore;
12
+ const { NumericSet } = memlabCore;
13
13
  import { getSnapshot, getSnapshotMetadata } from '../heap-state.js';
14
- import { errorResult, toolResult, formatBytes, formatNumber, markdownTable, truncateNodeName, } from '../utils.js';
14
+ import { checkAnalysisDeadline } from '../analysis-budget.js';
15
+ import { errorResult, toolResult, formatBytes, formatNumber, markdownTable, truncateNodeName, suggestionsSuppressed, boundedDominatorRetainedSize, } from '../utils.js';
15
16
  export function registerClassHistogram(server) {
16
- server.tool('memlab_class_histogram', 'Show instance count and total self size per constructor/class name, sorted by aggregate retained size (dominator-aware, no double-counting). Useful for identifying which types of objects dominate memory. Use min_count or min_retained_size to filter large histograms. Follow up with memlab_find_nodes_by_class to inspect specific classes, or memlab_retainer_trace on a sample node to see why objects are retained.', {
17
+ server.tool('memlab_class_histogram', 'Show per-constructor/class instance count and total self size. Useful for identifying which types of objects dominate memory. ' +
18
+ 'By DEFAULT (`include_retained_size:false`) it returns a counts + self-size histogram in a single O(N) pass with NO dominator walk — fast and safe on snapshots with millions of nodes; rows are sorted by self size. ' +
19
+ '⚠ Only pass `include_retained_size:true` when the user EXPLICITLY asks for dominator-aware retained sizes: that path walks the dominator tree and is the slow/memory-heavy part on large heaps. To stay tractable it then computes EXACT retained only for the heaviest `max_retained_classes` non-leaf classes (flat string/number classes are exact for free) and marks the rest with an upper-bound "~"; even so, on very large heaps with deep PromiseReaction/Context chains it can be slow and may hit the analysis time budget (returning "~" estimates) or, on older unbounded builds, time out the request entirely. ' +
20
+ 'Use min_count/min_self_size/min_retained_size to filter. Follow up with memlab_find_nodes_by_class to inspect specific classes, or memlab_retainer_trace on a sample node to see why objects are retained.', {
17
21
  limit: z
18
22
  .number()
19
23
  .optional()
@@ -27,7 +31,7 @@ export function registerClassHistogram(server) {
27
31
  min_retained_size: z
28
32
  .number()
29
33
  .optional()
30
- .describe('Minimum aggregate retained size in bytes to include. Use to filter to classes consuming significant memory (e.g., 1048576 for 1 MB).'),
34
+ .describe('Minimum aggregate retained size in bytes to include. Use to filter to classes consuming significant memory (e.g., 1048576 for 1 MB). Ignored when include_retained_size is false.'),
31
35
  min_self_size: z
32
36
  .number()
33
37
  .optional()
@@ -36,15 +40,41 @@ export function registerClassHistogram(server) {
36
40
  .string()
37
41
  .optional()
38
42
  .describe('Filter by node type (e.g., "object", "closure", "string"). If omitted, all types are included.'),
43
+ include_retained_size: z
44
+ .boolean()
45
+ .optional()
46
+ .default(false)
47
+ .describe('Compute dominator-aware retained sizes. DEFAULT false: the histogram returns counts + self sizes in a single O(N) pass (no dominator walk, no per-node id storage), which is fast and safe on snapshots with millions of nodes, sorted by self size. Set to true ONLY when the user explicitly asks for retained sizes — it walks the dominator tree and, on very large heaps (e.g. deep PromiseReaction/Context chains), can be slow and may hit the analysis time budget (returning upper-bound "~" estimates) or, on older unbounded builds, time out the request. When true, output is sorted by retained size.'),
48
+ max_retained_classes: z
49
+ .number()
50
+ .optional()
51
+ .default(64)
52
+ .describe('Cap on how many of the heaviest classes get an EXACT dominator-deduped retained size (default 64). Bounds the expensive dominator walk + id storage. Classes beyond this cap (and not leaf string/number types) show an upper-bound estimate marked "~". Raise for more exact rows at higher cost; this only matters when there are many large classes.'),
53
+ max_dominator_walk: z
54
+ .number()
55
+ .optional()
56
+ .default(500)
57
+ .describe('Cap on how many steps the per-instance dominator-up-walk takes when deduping retained size (default 500). Bounds the cost on heaps with pathologically deep dominator chains (e.g. long PromiseReaction linked lists) that would otherwise make the walk super-linear. If a class has instances whose nearest in-set dominator is deeper than this, its retained size becomes an upper-bound estimate marked "~". Raise for more accuracy at higher cost.'),
39
58
  suppress_suggestions: z
40
59
  .boolean()
41
60
  .optional()
42
61
  .default(false)
43
62
  .describe('Omit "Suggested next steps" boilerplate from the output to save tokens.'),
44
- }, async ({ limit, min_count, min_retained_size, min_self_size, node_type, suppress_suggestions, }) => {
63
+ }, async ({ limit, min_count, min_retained_size, min_self_size, node_type, include_retained_size, max_retained_classes, max_dominator_walk, suppress_suggestions, }) => {
45
64
  try {
46
65
  const snapshot = getSnapshot();
47
66
  const meta = getSnapshotMetadata();
67
+ // Flat strings and numbers are leaf nodes: they dominate nothing but
68
+ // themselves, so instances never overlap on the dominator tree and a
69
+ // raw sum of retainedSize equals the dominator-deduped value exactly.
70
+ // (Cons/sliced strings have other node types and are NOT treated as
71
+ // leaves.) This lets us skip the dominator walk for the millions of
72
+ // string/number nodes that usually dominate node count.
73
+ const LEAF_TYPES = new Set(['string', 'number']);
74
+ // Pass 1: counts + self size + RAW retained sum per class. No per-node
75
+ // id storage and no dominator walk — pure O(N). raw_retained is an
76
+ // UPPER BOUND on the dominator-deduped retained (dedup only removes
77
+ // overlap), which lets us pick exact-computation candidates cheaply.
48
78
  const classMap = new Map();
49
79
  snapshot.nodes.forEach(node => {
50
80
  if (node_type && node.type !== node_type)
@@ -57,64 +87,137 @@ export function registerClassHistogram(server) {
57
87
  if (entry) {
58
88
  entry.count++;
59
89
  entry.total_self_size += node.self_size;
60
- entry.node_ids.add(node.id);
90
+ entry.raw_retained += node.retainedSize;
61
91
  }
62
92
  else {
63
93
  classMap.set(key, {
64
94
  count: 1,
65
95
  total_self_size: node.self_size,
66
- node_ids: new NumericSet([node.id]),
96
+ raw_retained: node.retainedSize,
67
97
  type: node.type,
68
98
  });
69
99
  }
70
100
  });
71
- // Filter by min_count and min_self_size first, then compute
72
- // retained sizes only for classes that pass to avoid expensive
73
- // dominator walks on classes we'll discard anyway.
101
+ // Filter by cheap criteria first.
74
102
  let filtered = [...classMap.entries()].filter(([, v]) => v.count >= min_count);
75
103
  if (min_self_size != null) {
76
104
  filtered = filtered.filter(([, v]) => v.total_self_size >= min_self_size);
77
105
  }
78
- // Compute dominator-aware aggregate retained size per class.
79
- const withRetained = filtered.map(([key, v]) => {
80
- const retainedSize = utils.aggregateDominatorMetrics(v.node_ids, snapshot, () => true, (node) => node.retainedSize);
81
- return { key, ...v, retained_size: retainedSize };
82
- });
83
- // Apply min_retained_size filter after dominator walk
84
- let afterRetainedFilter = withRetained;
85
- if (min_retained_size != null) {
86
- afterRetainedFilter = withRetained.filter(v => v.retained_size >= min_retained_size);
106
+ let computed;
107
+ let anyEstimate = false;
108
+ if (!include_retained_size) {
109
+ // Fast path: no retained size at all. O(N) total, sorted by self size.
110
+ computed = filtered.map(([key, v]) => ({
111
+ key,
112
+ type: v.type,
113
+ count: v.count,
114
+ total_self_size: v.total_self_size,
115
+ retained_size: v.total_self_size,
116
+ retained_exact: false,
117
+ }));
118
+ computed.sort((a, b) => b.total_self_size - a.total_self_size);
119
+ }
120
+ else {
121
+ // Pick the heaviest NON-LEAF classes (by raw retained, the upper
122
+ // bound) to receive an exact dominator-deduped retained size. Leaf
123
+ // (string/number) classes are already exact via raw_retained.
124
+ const candidateKeys = filtered
125
+ .filter(([, v]) => !LEAF_TYPES.has(v.type))
126
+ .sort((a, b) => b[1].raw_retained - a[1].raw_retained)
127
+ .slice(0, Math.max(0, max_retained_classes))
128
+ .map(([key]) => key);
129
+ // Pass 2 (only if there are candidates): collect node ids for the
130
+ // candidate classes ONLY, so id storage is bounded to those classes
131
+ // instead of the whole heap.
132
+ const idsByClass = new Map();
133
+ for (const key of candidateKeys)
134
+ idsByClass.set(key, new NumericSet());
135
+ if (idsByClass.size > 0) {
136
+ snapshot.nodes.forEach(node => {
137
+ if (node.id <= 3)
138
+ return;
139
+ if (node_type && node.type !== node_type)
140
+ return;
141
+ if (LEAF_TYPES.has(node.type))
142
+ return;
143
+ const key = `${node.type}::${node.name}`;
144
+ const set = idsByClass.get(key);
145
+ if (set)
146
+ set.add(node.id);
147
+ });
148
+ }
149
+ computed = filtered.map(([key, v]) => {
150
+ // The dominator walk below does not flow through the instrumented
151
+ // snapshot.nodes.forEach, so check the deadline once per class to
152
+ // bound a runaway aggregation to a single class.
153
+ checkAnalysisDeadline();
154
+ let retained = v.raw_retained;
155
+ let exact = LEAF_TYPES.has(v.type);
156
+ const ids = idsByClass.get(key);
157
+ if (ids) {
158
+ // Bounded dominator-up-walk (max_dominator_walk steps) instead of
159
+ // @memlab's unbounded aggregateDominatorMetrics, so a deep
160
+ // dominator chain can't make one class's aggregation blow up. If
161
+ // the walk is truncated the size is an upper-bound estimate.
162
+ const r = boundedDominatorRetainedSize(ids, snapshot, max_dominator_walk);
163
+ retained = r.retained;
164
+ exact = r.exact;
165
+ }
166
+ if (!exact)
167
+ anyEstimate = true;
168
+ return {
169
+ key,
170
+ type: v.type,
171
+ count: v.count,
172
+ total_self_size: v.total_self_size,
173
+ retained_size: retained,
174
+ retained_exact: exact,
175
+ };
176
+ });
177
+ if (min_retained_size != null) {
178
+ computed = computed.filter(v => v.retained_size >= min_retained_size);
179
+ }
180
+ computed.sort((a, b) => b.retained_size - a.retained_size);
87
181
  }
88
182
  // Use total heap size as the denominator for cumulative % so it
89
183
  // reflects each class's share of the entire heap, not just the
90
184
  // filtered subset.
91
185
  const totalRetainedAll = meta?.totalSize ?? 0;
92
- const sorted = afterRetainedFilter
93
- .sort((a, b) => b.retained_size - a.retained_size)
94
- .slice(0, limit);
95
- const headers = [
96
- 'Class',
97
- 'Type',
98
- 'Count',
99
- 'Self Size',
100
- 'Retained Size',
101
- 'Cum %',
102
- ];
103
- const rightCols = new Set([2, 3, 4, 5]);
186
+ const sorted = computed.slice(0, limit);
187
+ const headers = include_retained_size
188
+ ? ['Class', 'Type', 'Count', 'Self Size', 'Retained Size', 'Cum %']
189
+ : ['Class', 'Type', 'Count', 'Self Size'];
190
+ const rightCols = include_retained_size
191
+ ? new Set([2, 3, 4, 5])
192
+ : new Set([2, 3]);
104
193
  let cumRetained = 0;
194
+ let shownEstimate = false;
105
195
  const rows = sorted.map(v => {
106
196
  const rawName = v.key.split('::').slice(1).join('::');
107
197
  const name = truncateNodeName(rawName, v.type, Math.round(v.total_self_size / v.count), 120);
198
+ if (!include_retained_size) {
199
+ return [
200
+ name,
201
+ v.type,
202
+ formatNumber(v.count),
203
+ formatBytes(v.total_self_size),
204
+ ];
205
+ }
108
206
  cumRetained += v.retained_size;
109
207
  const cumPct = totalRetainedAll > 0
110
208
  ? ((cumRetained / totalRetainedAll) * 100).toFixed(1) + '%'
111
209
  : '-';
210
+ const retainedCell = v.retained_exact
211
+ ? formatBytes(v.retained_size)
212
+ : `~${formatBytes(v.retained_size)}`;
213
+ if (!v.retained_exact)
214
+ shownEstimate = true;
112
215
  return [
113
216
  name,
114
217
  v.type,
115
218
  formatNumber(v.count),
116
219
  formatBytes(v.total_self_size),
117
- formatBytes(v.retained_size),
220
+ retainedCell,
118
221
  cumPct,
119
222
  ];
120
223
  });
@@ -123,7 +226,13 @@ export function registerClassHistogram(server) {
123
226
  '',
124
227
  markdownTable(headers, rows, rightCols),
125
228
  ];
126
- if (!suppress_suggestions) {
229
+ if (!include_retained_size) {
230
+ lines.push('', '_Retained size omitted (the default `include_retained_size:false`) for speed — sorted by self size. Only if the user explicitly wants dominator-aware retained sizes, re-run with `include_retained_size:true` (optionally with a high `min_self_size`/`min_count`); that path can be slow and may time out on very large heaps._');
231
+ }
232
+ else if (shownEstimate || anyEstimate) {
233
+ lines.push('', `_Rows marked "~" show an upper-bound retained size (may double-count nested objects). A row is estimated when it is outside the heaviest ${formatNumber(max_retained_classes)} non-leaf classes (raise \`max_retained_classes\`), or when an instance's nearest dominating instance is deeper than the ${formatNumber(max_dominator_walk)}-step walk cap (raise \`max_dominator_walk\`). String/number rows are always exact._`);
234
+ }
235
+ if (!suppress_suggestions && !suggestionsSuppressed()) {
127
236
  const highCount = sorted.filter(v => v.count >= 1000);
128
237
  if (highCount.length > 0) {
129
238
  lines.push('', '**Suggested next steps:**');