Указатели и escape-анализ: что уезжает в кучу и почему это важно
В Go нет ручного управления памятью и нет арифметики указателей: указатель — это просто способ дать доступ к тому же значению, а не к его копии. Где значение живёт — на стеке или в куче — решает не программист и не new, а компилятор через escape-анализ. Если он может доказать, что значение не переживёт вызова функции, оно остаётся на стеке и не нагружает сборщик мусора; если нет — «убегает» в кучу. Убегает оно в типичных случаях: возвращается указатель на локальную переменную (в Go это безопасно, в отличие от C), значение попадает в интерфейс, замыкание захватывает переменную, размер неизвестен на этапе компиляции. Практическая ценность в том, что это можно посмотреть: go build -gcflags=-m печатает решения компилятора. Отсюда и главный вывод: указатель ради «эффективности» часто даёт обратный эффект — маленькая структура по значению остаётся на стеке, а указатель на неё уезжает в кучу.