A goroutine leak occurs when a goroutine is started but never terminates, typically because it is blocked indefinitely on a channel send or receive, causing memory and CPU usage to grow until the program crashes. Prevent leaks by ensuring every goroutine has a clear exit condition, such as using a context.Context to signal cancellation or closing channels to unblock receivers. Use runtime/pprof to profile active goroutines and identify stuck routines:
import (
"context"
"runtime/pprof"
"time"
)
func worker(ctx context.Context) {
select {
case <-ctx.Done():
return // Exit on cancellation
case <-time.After(time.Second):
// Do work
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
go worker(ctx)
// Profile goroutines
pprof.Lookup("goroutine").WriteTo(os.Stdout, 2)
cancel()
}