Go Escape Analysis — Cheatsheet

Quick reference · pairs with Lesson 6

The rule

A value lives on the STACK if the compiler can prove it does not outlive its function. Otherwise it escapes to the heap. Decided at compile time, per value. Not about new, not about pointer-vs-value — only about proven lifetime.

Inspect it

go build -gcflags=-m ./...        # escape + inline decisions
go build -gcflags='-m -m' ./pkg  # verbose reasoning
go test -gcflags=-m -run=x ./pkg # same, on test builds
go test -bench=. -benchmem        # allocs/op & B/op — the payoff metric

What the output means

-m lineMeaning
moved to heap: xx escaped — heap allocated
&x escapes to heapthe address of x leaks past the frame
x escapes to heapx boxed into interface / leaked
x does not escapestays on the stack — free
inlining call to ff's body pasted in; can change escape results

Escapes to heap

Forces the heap
Stays on the stack

Cost model

 StackHeap
Allocatebump pointer — ~freeallocator + GC bookkeeping
Freeframe popGC cycle (later)
In allocs/opnoyes
OOM riskbounded by framegrows with live set × request rate

Mission connection (OOM)

A whole-file []byte read is runtime-sized and returned → heap, sized to the file. Multiply by concurrent requests → OOM. Streaming (io.Pipe, io.Copy) keeps only a small fixed buffer live per request. See Lesson 3.