Golang / Golang Internals and Memory Management Interview Questions
What are goroutine leaks and how do you detect and prevent them?
A goroutine leak occurs when a goroutine is started but never terminates — it blocks forever waiting on a channel, lock, or I/O operation that will never complete. Leaked goroutines consume memory (their stacks) and may hold references that prevent other objects from being GC'd. In a long-running server, goroutine leaks cause steady memory growth until OOM.
// Common leak pattern 1: unbuffered channel with no receiver func leak1() { ch := make(chan int) go func() { ch <- 42 // blocks forever â nobody reads }() // function returns; the goroutine is stuck sending forever } // Fix: use a buffered channel, or ensure the receiver runs func fixed1() { ch := make(chan int, 1) // buffered: sender doesn't block go func() { ch <- 42 }() // or: read from ch here before returning } // Common leak pattern 2: no cancellation signal func leak2(ctx context.Context, jobs <-chan Job) { go func() { for { job := <-jobs // blocks if jobs is never closed or ctx cancelled process(job) } }() } // Fix: use select with ctx.Done() func fixed2(ctx context.Context, jobs <-chan Job) { go func() { for { select { case <-ctx.Done(): return // clean exit on cancellation case job := <-jobs: process(job) } } }() } // Detecting leaks // 1. runtime.NumGoroutine() â spot trend in tests or monitoring // 2. http://localhost:6060/debug/pprof/goroutine?debug=2 â full traces // 3. goleak library (uber-go/goleak) â assert no goroutines leak in tests // import goleak "go.uber.org/goleak" // func TestMyFunc(t *testing.T) { // defer goleak.VerifyNone(t) // myFunc() // }
More Related questions...