Go garbage collection
Go automatically frees heap memory when heap allocated memory does not
have reference. We never call free or delete.
Pause times are kept low.
Go routines live on heap in
Go process memory layout
Garbage collector lies on Process's Text Area/Code Area section
Simple example (Linked List)
|
Suppose Later
|
How GC works = Tri-color Marking(White, Grey, Black)
These are 3 buckets:
| Bucket | White | Grey | Black |
|---|---|---|---|
| Meaning | Garbage | Reachable, but work remains | Reachable and fully scanned |
root
|
v
[A] ---> [B] ---> [C]
time 0. White=A,B,C
time 1. Grey=A, White=B,C // A(Reachable, but work remains)
time 2. Black=A, Grey=B, White=C // A(Reachable and fully scanned), B(Reachable, but work remains)
Why tri color scheme
Go doesn't want to stop the entire application while it scans the
heap.
Go's GC is concurrent, ie it keeps marking while you keep on allocating
heap. stop-the-world (STW) phases should be low
Go vs Java GC
Same core idea: both are tracing collectors — start from roots, follow references, reclaim what is unreachable. Neither requires you to free individual objects on the heap.
| Go | Java | |
|---|---|---|
| Heap model | Single Go heap (+ goroutine stacks on heap) | Object heap + separate metaspace for class metadata |
| Generations | Non-generational — no Eden / Old gen split | Generational — Eden, survivor spaces, old generation (most collectors) |
| Concurrency | Mark-and-sweep, mostly concurrent with app code | Depends on collector (G1, ZGC, etc.); young GC often STW, modern collectors reduce pauses |
| Roots | Goroutine stacks, globals, CPU registers | Java thread stacks, static fields, JNI refs, etc. |
| What gets collected | Heap objects; stack frames scanned for pointers | Heap objects only (class data in metaspace, not GC’d like objects) |
| Allocation path | Escape analysis — locals may stay on stack or move to heap | Almost all objects allocated on heap (new) |
Tuning GC
GOGC (default 100) — heap growth vs GC
frequency. Higher = less frequent GC, more memory.
GODEBUG=gctrace=1 — print GC stats to stderr (useful when
learning or debugging pauses).
Reduce unnecessary heap allocations (reuse buffers, avoid allocations in
hot loops) — same advice as Java, but Go has no generational “Eden is
cheap” assumption to the same degree.