Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Golang: goroutine, concurrency, memory leak, goroutine leak, resource exhaustion

Почему нельзя бесконтрольно создавать goroutine?

Вопрос проверяет понимание модели конкурентности в Go и рисков, связанных с неограниченным созданием горутин, включая утечки памяти и исчерпание ресурсов.

Короткий ответ

Бесконтрольное создание горутин может привести к исчерпанию памяти и ресурсов системы, так как каждая горутина занимает стек (минимум 2 КБ) и требует времени на планирование. Если горутины не завершаются или блокируются, они накапливаются, вызывая утечки памяти и падение производительности. Важно использовать пулы горутин или контексты с таймаутами для контроля их жизненного цикла.

Длинный ответ

Почему нельзя бесконтрольно создавать горутины?

Горутины в Go — это легковесные потоки, которые управляются рантаймом. Однако их создание без ограничений может привести к серьезным проблемам. Каждая горутина требует выделения стека (начиная с 2 КБ), который может расти до 1 ГБ при необходимости. Если горутины создаются в цикле или рекурсивно, они быстро исчерпывают доступную память.

Основные риски

  • Утечка памяти: Горутины, которые не завершаются (например, из-за блокировки на канале или бесконечного цикла), остаются в памяти, увеличивая потребление ресурсов.
  • Исчерпание ресурсов планировщика: Рантайм Go использует M:N планирование, где M — потоки ОС, N — горутины. Слишком много горутин замедляет планирование и увеличивает накладные расходы на переключение контекста.
  • Паника и нестабильность: При превышении лимитов памяти (например, ulimit) программа может аварийно завершиться.

Пример проблемы

package main

import (
    "fmt"
    "time"
)

func main() {
    for i := 0; i < 1000000; i++ {
        go func() {
            time.Sleep(time.Hour) // горутина висит час
        }()
    }
    fmt.Println("Горутины созданы")
    time.Sleep(time.Minute)
}

Этот код создаст миллион горутин, каждая из которых будет ждать час. Память быстро закончится, и программа упадет с ошибкой OOM (Out of Memory).

Как контролировать горутины?

  • Используйте контексты с таймаутами или отменой: context.WithCancel или context.WithTimeout позволяют завершить горутину принудительно.
  • Применяйте пулы горутин: Например, через буферизированные каналы или библиотеки типа errgroup.
  • Ограничивайте количество через семафоры: Используйте канал с буфером как семафор для лимита параллельных горутин.

Пример с контролем

package main

import (
    "context"
    "fmt"
    "time"
)

func worker(ctx context.Context, id int) {
    select {
    case <-time.After(time.Second):
        fmt.Printf("Worker %d done\n", id)
    case <-ctx.Done():
        fmt.Printf("Worker %d cancelled\n", id)
    }
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    for i := 0; i < 10; i++ {
        go worker(ctx, i)
    }
    time.Sleep(3 * time.Second)
}

Здесь все горутины завершатся через 2 секунды благодаря контексту, что предотвращает утечку.

Вывод: Бесконтрольное создание горутин опасно из-за риска утечек памяти и падения производительности. Всегда используйте механизмы управления жизненным циклом (контексты, пулы, семафоры) для безопасной работы с конкурентностью в Go.

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • Golang

    Golang

Ключевые слова

#goroutine

#concurrency

#memory leak

#goroutine leak

#resource exhaustion

Подпишись на Golang Developer в телеграм

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.