Memory leak xảy ra khi program allocate memory nhưng không release, dần dần RSS tăng cho đến khi OOM.
Nguyên nhân phổ biến:
- global/module-level variables tích lũy data.
- event listeners không được removeListener.
- closures capture large objects.
- circular references (trong ngôn ngữ reference-counted).
- unbounded cache/map.
- timer setInterval không clearInterval.
Trong Node.js: dùng node --inspect + Chrome DevTools Memory tab để heap snapshot và so sánh; clinic.js heapprofiler cho production; process.memoryUsage().heapUsed monitor; WeakMap/WeakRef cho cache để GC tự thu dọn khi key không còn reference.
Trong Go: goroutine leak (goroutine blocked trên channel mãi mãi, không bao giờ exit) là phổ biến hơn memory leak; dùng pprof heap/goroutine profiler; runtime.ReadMemStats để monitor.
Best practice: giới hạn size của in-memory cache; dùng context cancellation để goroutines tự cleanup; integration test monitor memory growth theo thời gian.
A memory leak occurs when a program allocates memory but never releases it, causing RSS to grow steadily until an OOM kill.
Common causes:
- Global or module-level variables accumulating data.
- Event listeners that are never removed.
- Closures capturing large objects.
- Circular references in reference-counted languages.
- Unbounded caches or maps.
- setInterval timers that are never cleared.
In Node.js: use node --inspect + the Chrome DevTools Memory tab to take and compare heap snapshots; clinic.js heapprofiler for production profiling; monitor process.memoryUsage().heapUsed; use WeakMap/WeakRef for caches so the GC can collect entries when keys are no longer referenced.
In Go: goroutine leaks (a goroutine blocked on a channel forever, never exiting) are more common than memory leaks; use pprof for heap and goroutine profiling; use runtime.ReadMemStats for monitoring.
Best practices: cap the size of in-memory caches; use context cancellation so goroutines clean up on shutdown; write integration tests that monitor memory growth over time.