Stack vs. Heap: Where Go Puts Your Data
The stack is a fast, last-in-first-out region for local, fixed-size data. The heap is slower, flexible memory for dynamic data or values that escape a function's scope.
WHY IT EXISTS: All running programs must manage memory. The stack and heap are two memory regions available for this, each offering a different trade-off. The stack provides extreme speed for data with a clear, predictable lifetime, while the heap offers flexibility for data whose size or lifetime is unknown at compile time.
THE MENTAL MODEL: The stack is like a neat pile of plates. You add plates to the top and take them from the top (last-in, first-out or LIFO). It's rigid but very fast. The heap is like finding a table at a restaurant; you ask for a certain amount of space, and the host (memory allocator) finds a spot and gives you its location (a pointer). This is more flexible but requires more work.
HOW IT WORKS: The stack stores values for the currently executing function, like its local variables and arguments. When the function returns, its entire section of the stack (its "stack frame") is instantly cleared. This is fast because it requires no searching; the location is always the top of the stack. A key constraint is that all data on the stack must have a known, fixed size.
The heap is for data that doesn't fit the stack's rules. When you need heap memory, the allocator finds a free block of the right size, marks it as used, and returns a pointer to it. This process is slower. Accessing the data is also slower because it involves an extra step: following the pointer from the stack to the heap location. In Go, the garbage collector periodically scans the heap to find and free memory that is no longer in use.
Go's compiler uses a process called "escape analysis" to decide where to store a variable. If a variable's lifetime can be determined at compile time to be confined to its function, it's placed on the stack. If it might be referenced after the function returns, it "escapes" to the heap.
WHEN TO USE IT: Go automatically uses the stack for most local variables like integers, booleans, and structs, as long as they don't escape. This is the default and most performant option. Go uses the heap for data that must outlive the function that created it, or for data structures that are inherently dynamic, like the backing arrays for slices and maps.
WHEN NOT TO USE IT: The primary footgun is causing unnecessary heap allocations. Every heap allocation adds pressure on the garbage collector, which can lead to performance degradation and application pauses. For example, returning a pointer to a small struct from a function forces a heap allocation, when returning the struct by value might have been a faster stack copy. Understanding escape analysis helps you write more performant code by minimizing these unintended heap allocations.
ONE CANONICAL EXAMPLE: Consider a function that returns a new object. If a function makeUser() returns a User struct directly, the struct value is typically copied on the stack. If another function newUser() returns a *User (a pointer), the compiler sees that the User object must exist after newUser returns. It therefore "escapes" and is allocated on the heap. The pointer itself, being a small fixed-size address, is then returned on the stack.
Read the original → doc.rust-lang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.