Ответ
Куча (heap) — это область в оперативной памяти, где Go хранит динамически выделяемые объекты. В отличие от стека, память в куче управляется не компилятором, а сборщиком мусора (Garbage Collector, GC).
Куча vs. Стек
Характеристика | Стек (Stack) | Куча (Heap) |
---|---|---|
Скорость | Очень быстрый доступ (LIFO) | Более медленный доступ |
Назначение | Локальные переменные, вызовы функций | Объекты, переживающие вызов функции, разделяемые данные |
Управление | Автоматическое (компилятор) | Автоматическое (сборщик мусора) |
Размер | Фиксированный и небольшой | Динамический и большой |
Escape Analysis (Анализ "убегания")
Компилятор Go решает, где выделить переменную — в стеке или в куче. Этот процесс называется escape analysis. Переменная "убегает" в кучу, если:
- На нее возвращается указатель из функции.
- Она отправляется в канал или используется в другой горутине.
- Ее размер неизвестен на этапе компиляции (например, слайс, размер которого определяется в рантайме).
Пример:
// Эта функция заставит 's' "убежать" в кучу,
// так как указатель на слайс возвращается наружу.
func createSlice() *[]int {
s := make([]int, 1000) // s выделяется в куче
return &s
}
// В этой функции 's' останется в стеке,
// так как используется только локально.
func createLocalSlice() {
s := make([]int, 10) // s, скорее всего, будет выделен в стеке
s[0] = 1
}
Влияние на производительность
Частое выделение памяти в куче создает нагрузку на сборщик мусора (GC). Работа GC может приводить к коротким остановкам программы (stop-the-world
), что критично для высокопроизводительных приложений. Поэтому хорошей практикой в Go является минимизация аллокаций в куче, где это возможно.
Проанализировать "убегание" можно с помощью флага компилятора:
go build -gcflags="-m" ./...