@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.
- package/README.md +73 -3
- package/dist/analysis-budget.d.ts +71 -0
- package/dist/analysis-budget.d.ts.map +1 -0
- package/dist/analysis-budget.js +118 -0
- package/dist/analysis-budget.js.map +1 -0
- package/dist/guardrail.d.ts +24 -0
- package/dist/guardrail.d.ts.map +1 -0
- package/dist/guardrail.js +65 -0
- package/dist/guardrail.js.map +1 -0
- package/dist/heap-state.d.ts +46 -1
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +142 -10
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +36 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/array-group-by.d.ts +12 -0
- package/dist/tools/array-group-by.d.ts.map +1 -0
- package/dist/tools/array-group-by.js +191 -0
- package/dist/tools/array-group-by.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +999 -37
- package/dist/tools/auto-investigate.js.map +1 -1
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +438 -21
- package/dist/tools/cache-analysis.js.map +1 -1
- package/dist/tools/check-health.d.ts.map +1 -1
- package/dist/tools/check-health.js +261 -1
- package/dist/tools/check-health.js.map +1 -1
- package/dist/tools/class-histogram.d.ts.map +1 -1
- package/dist/tools/class-histogram.js +142 -33
- package/dist/tools/class-histogram.js.map +1 -1
- package/dist/tools/closure-inspection.d.ts.map +1 -1
- package/dist/tools/closure-inspection.js +238 -25
- package/dist/tools/closure-inspection.js.map +1 -1
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +25 -3
- package/dist/tools/detached-dom.js.map +1 -1
- package/dist/tools/dev-artifacts.d.ts +33 -0
- package/dist/tools/dev-artifacts.d.ts.map +1 -0
- package/dist/tools/dev-artifacts.js +165 -0
- package/dist/tools/dev-artifacts.js.map +1 -0
- package/dist/tools/diff-snapshots.d.ts.map +1 -1
- package/dist/tools/diff-snapshots.js +113 -18
- package/dist/tools/diff-snapshots.js.map +1 -1
- package/dist/tools/duplicated-strings.d.ts.map +1 -1
- package/dist/tools/duplicated-strings.js +74 -12
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +189 -10
- package/dist/tools/eval.js.map +1 -1
- package/dist/tools/event-listener-leaks.d.ts.map +1 -1
- package/dist/tools/event-listener-leaks.js +235 -13
- package/dist/tools/event-listener-leaks.js.map +1 -1
- package/dist/tools/event-registry.d.ts +12 -0
- package/dist/tools/event-registry.d.ts.map +1 -0
- package/dist/tools/event-registry.js +183 -0
- package/dist/tools/event-registry.js.map +1 -0
- package/dist/tools/find-by-property.d.ts.map +1 -1
- package/dist/tools/find-by-property.js +113 -31
- package/dist/tools/find-by-property.js.map +1 -1
- package/dist/tools/find-by-shape.d.ts +12 -0
- package/dist/tools/find-by-shape.d.ts.map +1 -0
- package/dist/tools/find-by-shape.js +178 -0
- package/dist/tools/find-by-shape.js.map +1 -0
- package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
- package/dist/tools/find-nodes-by-class.js +50 -6
- package/dist/tools/find-nodes-by-class.js.map +1 -1
- package/dist/tools/for-each.d.ts.map +1 -1
- package/dist/tools/for-each.js +1 -1
- package/dist/tools/for-each.js.map +1 -1
- package/dist/tools/get-node.d.ts.map +1 -1
- package/dist/tools/get-node.js +6 -0
- package/dist/tools/get-node.js.map +1 -1
- package/dist/tools/get-string.d.ts +12 -0
- package/dist/tools/get-string.d.ts.map +1 -0
- package/dist/tools/get-string.js +223 -0
- package/dist/tools/get-string.js.map +1 -0
- package/dist/tools/get-value.d.ts +12 -0
- package/dist/tools/get-value.d.ts.map +1 -0
- package/dist/tools/get-value.js +152 -0
- package/dist/tools/get-value.js.map +1 -0
- package/dist/tools/global-variables.d.ts.map +1 -1
- package/dist/tools/global-variables.js +54 -34
- package/dist/tools/global-variables.js.map +1 -1
- package/dist/tools/growth-signals.d.ts +12 -0
- package/dist/tools/growth-signals.d.ts.map +1 -0
- package/dist/tools/growth-signals.js +211 -0
- package/dist/tools/growth-signals.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts +12 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -0
- package/dist/tools/intern-opportunities.js +289 -0
- package/dist/tools/intern-opportunities.js.map +1 -0
- package/dist/tools/load-snapshot.d.ts +10 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +152 -15
- package/dist/tools/load-snapshot.js.map +1 -1
- package/dist/tools/object-cost-breakdown.d.ts +12 -0
- package/dist/tools/object-cost-breakdown.d.ts.map +1 -0
- package/dist/tools/object-cost-breakdown.js +439 -0
- package/dist/tools/object-cost-breakdown.js.map +1 -0
- package/dist/tools/object-shape.d.ts.map +1 -1
- package/dist/tools/object-shape.js +95 -2
- package/dist/tools/object-shape.js.map +1 -1
- package/dist/tools/pinch-points.d.ts.map +1 -1
- package/dist/tools/pinch-points.js +9 -9
- package/dist/tools/pinch-points.js.map +1 -1
- package/dist/tools/property-distribution.d.ts +12 -0
- package/dist/tools/property-distribution.d.ts.map +1 -0
- package/dist/tools/property-distribution.js +168 -0
- package/dist/tools/property-distribution.js.map +1 -0
- package/dist/tools/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +56 -19
- package/dist/tools/quick-diagnosis.js.map +1 -1
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +90 -5
- package/dist/tools/retainer-summary.js.map +1 -1
- package/dist/tools/retainer-trace.d.ts.map +1 -1
- package/dist/tools/retainer-trace.js +74 -22
- package/dist/tools/retainer-trace.js.map +1 -1
- package/dist/tools/search-nodes.d.ts.map +1 -1
- package/dist/tools/search-nodes.js +10 -3
- package/dist/tools/search-nodes.js.map +1 -1
- package/dist/tools/search-strings.d.ts +12 -0
- package/dist/tools/search-strings.d.ts.map +1 -0
- package/dist/tools/search-strings.js +182 -0
- package/dist/tools/search-strings.js.map +1 -0
- package/dist/tools/sequence-analysis.d.ts +12 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -0
- package/dist/tools/sequence-analysis.js +234 -0
- package/dist/tools/sequence-analysis.js.map +1 -0
- package/dist/tools/server-status.d.ts +12 -0
- package/dist/tools/server-status.d.ts.map +1 -0
- package/dist/tools/server-status.js +41 -0
- package/dist/tools/server-status.js.map +1 -0
- package/dist/tools/shape-histogram.d.ts.map +1 -1
- package/dist/tools/shape-histogram.js +61 -16
- package/dist/tools/shape-histogram.js.map +1 -1
- package/dist/tools/sliced-strings.d.ts.map +1 -1
- package/dist/tools/sliced-strings.js +16 -11
- package/dist/tools/sliced-strings.js.map +1 -1
- package/dist/tools/snapshot-summary.d.ts.map +1 -1
- package/dist/tools/snapshot-summary.js +55 -13
- package/dist/tools/snapshot-summary.js.map +1 -1
- package/dist/tools/snapshots.d.ts +12 -0
- package/dist/tools/snapshots.d.ts.map +1 -0
- package/dist/tools/snapshots.js +93 -0
- package/dist/tools/snapshots.js.map +1 -0
- package/dist/tools/stale-collections.d.ts.map +1 -1
- package/dist/tools/stale-collections.js +248 -7
- package/dist/tools/stale-collections.js.map +1 -1
- package/dist/tools/trace-dominators.d.ts.map +1 -1
- package/dist/tools/trace-dominators.js +28 -1
- package/dist/tools/trace-dominators.js.map +1 -1
- package/dist/tools/weakmap-entries.d.ts +12 -0
- package/dist/tools/weakmap-entries.d.ts.map +1 -0
- package/dist/tools/weakmap-entries.js +156 -0
- package/dist/tools/weakmap-entries.js.map +1 -0
- package/dist/utils.d.ts +81 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +303 -35
- package/dist/utils.js.map +1 -1
- 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:
|
|
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;
|
|
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 {
|
|
12
|
+
const { NumericSet } = memlabCore;
|
|
13
13
|
import { getSnapshot, getSnapshotMetadata } from '../heap-state.js';
|
|
14
|
-
import {
|
|
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
|
|
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.
|
|
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
|
-
|
|
96
|
+
raw_retained: node.retainedSize,
|
|
67
97
|
type: node.type,
|
|
68
98
|
});
|
|
69
99
|
}
|
|
70
100
|
});
|
|
71
|
-
// Filter by
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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 =
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
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 (!
|
|
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:**');
|