Goroutine leak — горутина, которая никогда не завершится. Она висит в памяти, потребляя ресурсы. Типичные причины:
1. Забытый канал — никто не читает/пишет:
func leak() {
ch := make(chan int)
go func() {
ch <- 42 // блокируется навечно — никто не читает
}()
// ch нигде не читается, горутина утекла
}
2. Нет выхода из цикла:
go func() {
for {
// нет select с done-каналом — не остановить
doWork()
}
}()
Решение — всегда давай горутине выход:
func worker(ctx context.Context) {
for {
select {
case <-ctx.Done():
return // чистый выход
case job := <-jobs:
process(job)
}
}
}
Диагностика: runtime.NumGoroutine(), pprof (/debug/pprof/goroutine), или goleak в тестах.