Обнаружение утечек и отмена
Обеспечивайте завершение горутин и предотвращайте утечки
«Обнаружение утечек и отмена» — бесплатный урок 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 — локальная установка не требуется.
Все уроки этого курса
- Шаблоны конвейеров и этапов
- errgroup для конкурентной обработки ошибок
- Шаблон семафора
- Обнаружение утечек и отмена