Какой размер стека у горутины и сколько памяти она потребляет?

Ответ

Горутина — это легковесный поток исполнения, управляемый средой выполнения Go. Её потребление памяти состоит из двух основных частей:

  1. Стек (Stack):

    • Начальный размер стека — 2 КБ. Это значительно меньше, чем у системных потоков (обычно 1-8 МБ).
    • Стек горутины может динамически расти и сжиматься по мере необходимости, чтобы избежать переполнения (stack overflow). Память для стека выделяется в куче (heap).
  2. Структура управления (g):

    • Среда выполнения Go создает для каждой горутины внутреннюю структуру (известную как g), которая хранит её состояние (статус, указатель на стек и т.д.). Эта структура также занимает несколько сотен байт.

Итог:
Минимальное потребление памяти на одну горутину составляет ~2-4 КБ. Однако реальный расход зависит от глубины рекурсии и количества переменных, используемых в горутине.

Пример, демонстрирующий создание горутины (точное измерение памяти одной горутины затруднено из-за работы сборщика мусора и других фоновых процессов):

package main

import (
    "fmt"
    "runtime"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    var before, after runtime.MemStats

    runtime.ReadMemStats(&before)

    count := 10000
    for i := 0; i < count; i++ {
        wg.Add(1)
        go func() {
            // Пустая горутина для демонстрации
            wg.Done()
        }()
    }
    wg.Wait()

    runtime.ReadMemStats(&after)
    // Выводим средний размер, чтобы минимизировать погрешность
    fmt.Printf("Примерное потребление памяти на одну горутину: %d байтn", (after.TotalAlloc-before.TotalAlloc)/uint64(count))
}