Part 3 · 2 chapters · ~12 min

Memory, Leaks and GC

RSS against managed heap, heap dumps and snapshots per runtime (V8, JVM with Eclipse MAT, Go heap profiles, Python tracemalloc), off-heap and native memory, allocator fragmentation, GC logs and pause analysis, and container OOM kills.

7

Finding the kind of memory first

code
# Linux: break RSS down
pmap -x <pid> | sort -k3 -n | tail      # largest mappings
grep -E 'Rss|Anon|File' /proc/<pid>/smaps_rollup
# JVM: native memory tracking
java -XX:NativeMemoryTracking=summary ...; jcmd <pid> VM.native_memory summary
jcmd <pid> GC.heap_dump /tmp/heap.hprof        # open in Eclipse MAT: dominator tree, leak suspects
# Go
curl -s localhost:6060/debug/pprof/heap > heap.pb.gz && go tool pprof -sample_index=inuse_space heap.pb.gz
# Python
import tracemalloc; tracemalloc.start(25); ...; tracemalloc.take_snapshot().statistics('traceback')[:10]
WHERE DID THE MEMORY GO?
RSS is the sum of several kinds of memory; each has its own tool
RSSwhat the OS (and OOM killer) seesmanaged heapV8, JVM, Go, Python objectsoff-heapbuffers, direct memory, mmapnativeallocator, libraries, threadscode + stacksJIT code, thread stacks
swipe the figure sideways, or tap expand for full screen
1/5
RSS first
The container is killed on RSS, not on heap size. Compare RSS with the runtime's heap metrics: if they diverge, the growth is outside the managed heap.
OOM kills on RSScompare RSS with heap metrics
8

GC logs and pauses

runtimeGC visibilitypause-related levers
JVM-Xlog:gc*, JFRG1 (default, pause targets), ZGC and Shenandoah (sub-millisecond pauses), heap sizing
GoGODEBUG=gctrace=1GOGC (heap growth before GC), GOMEMLIMIT (soft limit, Go 1.19+)
Node--trace-gcold space size, semi-space size, allocation rate (Node course part 1)
Pythongc.set_debug, gc.callbacksreference counting frees most objects; the cycle collector handles cycles; gc.freeze() for forked workers

A common Go production setting: GOMEMLIMIT at about 90% of the container limit so the GC works harder before the OOM killer acts. The equivalent idea in Node is sizing old space below the limit.