Ответ
Анализ ускользания (escape analysis) — это процесс, который компилятор Go выполняет во время сборки, чтобы определить, где должна быть выделена память для переменной: на стеке или в куче.
Основная цель: Максимально использовать стек для выделения памяти, так как это намного быстрее и эффективнее, чем выделение в куче.
- Выделение на стеке: Очень быстрая операция, просто сдвиг указателя стека. Память освобождается автоматически при выходе из функции. Не создает нагрузки на сборщик мусора (GC).
- Выделение в куче (ускользание): Более медленная операция, требующая поиска подходящего блока памяти. Память для таких переменных должна отслеживаться и освобождаться сборщиком мусора, что создает дополнительную нагрузку.
Когда переменная «ускользает» в кучу?
- Возврат указателя: Если функция возвращает указатель на локальную переменную.
- Размер переменной: Если переменная слишком велика для размещения на стеке.
- Передача в другую горутину: Отправка указателя на переменную в канал.
- Непрямое использование: Сохранение указателя в срезе, карте или другой структуре данных, которая может пережить вызов функции.
Как проверить?
Можно использовать флаг -gcflags="-m"
при сборке, чтобы увидеть решения компилятора:
# Файл test.go
func createInt() *int {
x := 10
return &x // x "ускользает" в кучу
}
# Команда для анализа
go build -gcflags="-m" ./test.go
# Вывод компилятора покажет:
# ./test.go:3:9: moved to heap: x
Влияние на производительность: Чем меньше переменных «ускользает» в кучу, тем меньше работы для сборщика мусора, что приводит к снижению задержек (latency) и повышению общей производительности приложения.