В чем разница между стеком и кучей?

Ответ

Стек и куча — это области памяти, используемые для хранения данных, но с разными характеристиками:

  • Стек:

    • Выделяется автоматически (например, для локальных переменных).
    • Быстрый доступ, но ограниченный размер.
    • Освобождается при выходе из функции (LIFO - Last In, First Out).
    • В Go стек используется для локальных переменных и значений, которые, согласно анализу побега (escape analysis), не 'убегают' (escape) за пределы текущей функции. Это могут быть примитивы, структуры, массивы и даже заголовки слайсов/карт, если они не используются после завершения функции.
  • Куча:

    • Динамическое выделение памяти (например, через new или make).
    • Медленнее, но размер ограничен только ОЗУ.
    • Требует сборщика мусора (GC) для освобождения.
    • В Go куча хранит значения, которые 'убегают' (escape) за пределы области видимости их создания (например, возвращаются из функции, передаются по ссылке в другую горутину, или их размер неизвестен на этапе компиляции). Эти объекты требуют сборщика мусора для освобождения.
func main() {
    a := 42          // int, вероятно, в стеке (если не 'убегает')
    b := new(int)    // int в куче (возвращает указатель, значение 'убегает')
    *b = 42

    // Пример, где переменная может 'убежать' в кучу:
    ptr := createAndReturnPointer() // значение, на которое указывает ptr, будет в куче
    _ = ptr
}

func createAndReturnPointer() *int {
    x := 100 // x будет в куче, так как его адрес возвращается
    return &x
}

В Go решение о размещении данных на стеке или в куче принимается компилятором автоматически на основе анализа побега (escape analysis), что избавляет разработчика от ручного управления памятью.