Как устроен стек горутины и каковы его ограничения?

Ответ

Стек горутины в Go является динамически расширяемым, что является ключевой особенностью, позволяющей эффективно создавать миллионы горутин.

  • Начальный размер: Стек создается с очень маленьким размером, обычно 2 КБ (килобайта).
  • Динамический рост: Если горутине требуется больше места в стеке (например, при вызове вложенных функций), Go runtime автоматически выделяет новый, больший сегмент памяти и копирует в него текущий стек. Это происходит незаметно для программиста.
  • Максимальный размер: Чтобы предотвратить бесконтрольное потребление памяти (например, при бесконечной рекурсии), максимальный размер стека ограничен. По умолчанию это 1 ГБ на 64-битных системах. При превышении этого лимита программа паникует с ошибкой stack overflow.

Изменить максимальный размер стека для всей программы можно с помощью пакета runtime/debug, но это требуется крайне редко:

import "runtime/debug"

func main() {
    // Устанавливаем максимальный размер стека в 4 МБ
    debug.SetMaxStack(4 * 1024 * 1024)
}

Вывод: Динамические стеки позволяют Go экономно расходовать память, выделяя для каждой горутины ровно столько, сколько ей нужно в данный момент, что и делает их такими «легковесными».