Go сам решает, где разместить переменную — на стеке или в куче. Это называется escape analysis.
Стек — быстро, автоматически освобождается при выходе из функции. Куча — медленнее, нужен GC для очистки.
func stackAlloc() int {
x := 42 // остаётся на стеке
return x // копия значения
}
func heapAlloc() *int {
x := 42 // "убегает" (escapes) в кучу
return &x // указатель на локальную переменную — Go перемещает в heap
}
Проверка escape analysis:
go build -gcflags="-m" ./...
# ./main.go:10:2: moved to heap: x
Что вызывает escape на heap:
- Возврат указателя на локальную переменную
- Передача в интерфейс (компилятор не знает размер)
- Замыкание захватывает переменную
- Слайс растёт (realloc)
- Слишком большой объект для стека
sync.Pool, избегай ненужных аллокаций в горячем пути.