← Назад к вопросам

Какое ограничение размера стека в горутине?

1.8 Middle🔥 281 комментариев
#Конкурентность и горутины#Основы Go

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ограничение размера стека в горутине

В языке Go, стек горутины изначально имеет небольшой размер, который динамически растёт и сокращается по мере необходимости. Это ключевое отличие от потоков операционной системы, где стек обычно имеет фиксированный и значительный размер (часто 1-2 МБ или более).

Начальный размер стека

В современных версиях Go (начиная с 1.4, где была реализована непрерывная модель стеков - contiguous stack model) начальный размер стека горутины составляет:

  • 2 КБ для 64-битных систем
  • 1 КБ для 32-битных систем

Динамическое изменение размера

Система выполнения Go (runtime) автоматически управляет размером стека:

func recursiveCall(count int) {
    if count == 0 {
        return
    }
    var buffer [256]byte // Локальные переменные размещаются на стеке
    _ = buffer
    recursiveCall(count - 1)
}

В этом примере при глубокой рекурсии стек будет неоднократно расширяться.

Максимальный размер стека

Максимальный размер стека горутины зависит от архитектуры:

  • 1 ГБ на 64-битных системах
  • 250 МБ на 32-битных системах

Эти ограничения устанавливаются во время компиляции и определяются в исходном коде Go runtime. Проверить текущие значения можно, изучив исходный код runtime, но на практике эти лимиты достигаются крайне редко.

Управление размером стека

Размер стека контролируется переменной окружения GODEBUG:

export GODEBUG=stacksize=4096  # Установить начальный размер стека 4 КБ

Также можно использовать флаги линковки:

go build -ldflags "-X runtime/debug.stackSize=4096"

Практическое значение

  1. Эффективность использования памяти: Малые начальные стеки позволяют создавать миллионы горутин без чрезмерного потребления памяти
  2. Динамическое расширение: Стек растёт только при необходимости, что оптимизирует использование ресурсов
  3. Автоматическое сокращение: При уменьшении потребности в стеке Go runtime может его сократить

Пример возникновения переполнения стека

package main

func infiniteRecursion() {
    var x [1024]byte // Выделяем память на стеке
    _ = x
    infiniteRecursion() // Бесконечная рекурсия
}

func main() {
    infiniteRecursion()
}

Эта программа в конечном итоге приведёт к ошибке "stack overflow", когда будет достигнут максимальный размер стека.

Сравнение с системными потоками

КритерийГорутина в GoСистемный поток
Начальный размер стека1-2 КБ1-2 МБ (часто по умолчанию)
Максимальный размер250 МБ - 1 ГБОпределяется ОС, часто несколько ГБ
Управление стекомДинамическое, runtime GoФиксированное или с ограниченной динамикой
Стоимость создания2-8 КБ (включая стек)1-2 МБ + структуры ядра ОС

Рекомендации по работе

  • Избегайте глубокой рекурсии в чистом виде — используйте итеративные алгоритмы или явное управление состоянием
  • Переносите большие структуры данных в кучу (heap), если они могут переполнить стек
  • Используйте буферизованные каналы или срезы для передачи больших данных между горутинами
  • Помните о замыканиях, которые могут неожиданно удерживать большие объёмы данных на стеке

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

Какое ограничение размера стека в горутине? | PrepBro