Ответ
За выделение памяти в Go отвечают два ключевых компонента: компилятор и среда выполнения (runtime).
- Компилятор — на этапе компиляции проводит анализ побега (escape analysis). Он определяет, где безопаснее и эффективнее разместить переменную: в стеке или в куче.
- Среда выполнения (Runtime) — на основе решения компилятора производит фактическое выделение памяти в одном из двух мест:
- Стек (Stack): Быстрая память для локальных переменных, время жизни которых ограничено вызовом одной функции. Память освобождается автоматически при выходе из функции.
- Куча (Heap): Более медленная, но гибкая область памяти для данных, которые должны "пережить" вызов функции (например, если на них есть ссылки из других горутин или они возвращаются из функции). Память в куче управляется сборщиком мусора (GC).
func createObject() *int {
// Компилятор видит, что указатель на 'x' возвращается из функции,
// поэтому 'x' "сбегает" и будет размещена в куче.
x := 100
return &x
}