0Pricing
Go Academy · Урок

Обнаружение утечек и отмена

Обеспечивайте завершение горутин и предотвращайте утечки

«Обнаружение утечек и отмена» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Что такое утечка горутин

Утечка горутин возникает, когда горутина запускается, но никогда не завершается. Со временем утёкшие горутины накапливаются, потребляя память стека и ресурсы CPU, пока процесс не будет завершён.

Распространённая утечка: заблокированное получение из канала

Горутина, ожидающая получения из канала, который никогда не получает значение, блокируется навсегда:

go func() {
    v := <-ch // leaks if no sender and ch is never closed
    use(v)
}()

Распространённая утечка: отсутствие сигнала завершения

Горутина в цикле for без условия выхода или канала завершения выполняется бесконечно:

go func() {
    for {
        work()
        // no exit condition — leaks
    }
}()

Обнаружение утечек с помощью goleak

go.uber.org/goleak проверяет, не остались ли утёкшие горутины после завершения теста:

func TestMyFunc(t *testing.T) {
    defer goleak.VerifyNone(t)
    myFunc() // should not leak goroutines
}

Контекст как средство устранения проблемы

Идиоматичный способ остановить долго работающие горутины — использовать контекст. Передайте ctx горутине и выполняйте выбор по ctx.Done().

go func(ctx context.Context) {
    for {
        select {
        case work := <-workCh:
            process(work)
        case <-ctx.Done():
            return // clean exit
        }
    }
}(ctx)

Шаблон с каналом Done

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

done := make(chan struct{})
go func() {
    select {
    case v := <-data: use(v)
    case <-done: return
    }
}()
close(done) // stops goroutine

Обнаружение с помощью среды выполнения

Выводите количество горутин во время выполнения, чтобы обнаруживать их рост:

fmt.Println("goroutines:", runtime.NumGoroutine())

Горутины HTTP-сервера

net/http автоматически создаёт горутины для каждого запроса и очищает их после завершения запроса. Однако обработчики, запускающие горутины без их последующего завершения, всё равно могут создавать утечки.

Тестирование на наличие утечек

Запускайте набор тестов с goleak в TestMain или используйте defer для каждого теста. Любая горутина, не завершившаяся после тела теста, приводит к ошибке теста.

func TestMain(m *testing.M) {
    goleak.VerifyTestMain(m)
}

Утечки из-за time.After

time.After в select внутри цикла создаёт новый таймер на каждой итерации. Он не может быть освобождён сборщиком мусора, пока не сработает. Замените его на time.NewTimer и Reset.

Утечка из-за горутины, возвращающей ошибку

Если горутина должна отправить результат в канал, но из-за ошибки завершается досрочно и ничего не отправляет, горутина-получатель блокируется навсегда. Всегда отправляйте значение или закрывайте канал на всех путях выполнения.

Быстрая проверка

Каков наиболее идиоматичный способ остановить долго работающую горутину в Go?

Повторение: обнаружение утечек и отмена

Ключевые моменты:

  • Утечки горутин накапливаются; отслеживайте их с помощью runtime.NumGoroutine()
  • goleak автоматически обнаруживает утечки горутин в тестах
  • Всегда предоставляйте горутинам путь выхода: контекст, канал завершения или закрытый канал входных данных
  • time.After в циклах создаёт утечки таймеров; используйте NewTimer+Reset

Часто задаваемые вопросы

Урок «Обнаружение утечек и отмена» бесплатный?

Да — полный текст урока «Обнаружение утечек и отмена» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «Обнаружение утечек и отмена»?

Обеспечивайте завершение горутин и предотвращайте утечки Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

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

Сколько времени занимает урок «Обнаружение утечек и отмена»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Шаблоны конвейеров и этапов
  2. errgroup для конкурентной обработки ошибок
  3. Шаблон семафора
  4. Обнаружение утечек и отмена
← Назад к Go Academy