How does Go decide whether a variable lives on the stack or the heap?
The language spec does not mention stack or heap. The compiler decides, using escape analysis. If it can prove a value is never referenced after its function returns, and the value's size is known and not too large, the value goes in the goroutine's stack frame. Otherwise it "escapes" to the heap, where the garbage collector manages it.
Stack allocation is almost free: the stack pointer moves and the memory disappears when the frame is popped. Heap allocation goes through mallocgc, has to be zeroed, and adds work for the GC.
func onStack() int {
x := 42 // never outlives the frame: stays on the stack
return x
}
func onHeap() *int {
x := 42 // its address outlives the frame: moved to heap
return &x
}
Gotcha: new(T) and &T{} do not force heap allocation, and a plain local variable is not guaranteed to stay on the stack. C and Java intuitions do not apply here. Returning &x is also perfectly safe in Go.
What the interviewer is looking for: you know placement is a compiler decision that you can inspect, not something you choose with syntax.
More on Memory, GC & Runtime Internals
- Q332How do you inspect escape analysis decisions, and how do you read the output?
- Q333List the common reasons a value escapes to the heap.
- Q334How do goroutine stacks grow, and why does that constrain the language?
- Q335Describe Go's memory allocator: size classes, mcache/mcentral/mheap, and the tiny allocator.
- Q336Explain Go's concurrent tri-color mark-and-sweep garbage collector.
- Q337What is a write barrier and which one does Go use?