MCPcopy Index your code
hub / github.com/codeaashu/claude-code / captureMemoryDiagnostics

Function captureMemoryDiagnostics

src/utils/heapDumpService.ts:88–212  ·  view source on GitHub ↗
(
  trigger: 'manual' | 'auto-1.5GB',
  dumpNumber = 0,
)

Source from the content-addressed store, hash-verified

86 * This helps identify if the leak is in V8 heap (captured) or native memory (not captured).
87 */
88export async function captureMemoryDiagnostics(
89 trigger: 'manual' | 'auto-1.5GB',
90 dumpNumber = 0,
91): Promise<MemoryDiagnostics> {
92 const usage = process.memoryUsage()
93 const heapStats = getHeapStatistics()
94 const resourceUsage = process.resourceUsage()
95 const uptimeSeconds = process.uptime()
96
97 // getHeapSpaceStatistics() is not available in Bun
98 let heapSpaceStats: HeapSpaceInfo[] | undefined
99 try {
100 heapSpaceStats = getHeapSpaceStatistics()
101 } catch {
102 // Not available in Bun runtime
103 }
104
105 // Get active handles/requests count (these are internal APIs but stable)
106 const activeHandles = (
107 process as unknown as { _getActiveHandles: () => unknown[] }
108 )._getActiveHandles().length
109 const activeRequests = (
110 process as unknown as { _getActiveRequests: () => unknown[] }
111 )._getActiveRequests().length
112
113 // Try to count open file descriptors (Linux/macOS)
114 let openFileDescriptors: number | undefined
115 try {
116 openFileDescriptors = (await readdir('/proc/self/fd')).length
117 } catch {
118 // Not on Linux - try macOS approach would require lsof, skip for now
119 }
120
121 // Try to read Linux smaps_rollup for detailed memory breakdown
122 let smapsRollup: string | undefined
123 try {
124 smapsRollup = await readFile('/proc/self/smaps_rollup', 'utf8')
125 } catch {
126 // Not on Linux or no access - this is fine
127 }
128
129 // Calculate native memory (RSS - heap) and growth rate
130 const nativeMemory = usage.rss - usage.heapUsed
131 const bytesPerSecond = uptimeSeconds > 0 ? usage.rss / uptimeSeconds : 0
132 const mbPerHour = (bytesPerSecond * 3600) / (1024 * 1024)
133
134 // Identify potential leaks
135 const potentialLeaks: string[] = []
136 if (heapStats.number_of_detached_contexts > 0) {
137 potentialLeaks.push(
138 `${heapStats.number_of_detached_contexts} detached context(s) - possible iframe/context leak`,
139 )
140 }
141 if (activeHandles > 100) {
142 potentialLeaks.push(
143 `${activeHandles} active handles - possible timer/socket leak`,
144 )
145 }

Callers 1

performHeapDumpFunction · 0.85

Calls 4

readdirFunction · 0.85
readFileFunction · 0.85
getSessionIdFunction · 0.85
pushMethod · 0.45

Tested by

no test coverage detected