goroutine 泄漏指 goroutine 启动后永远无法退出,持续占用栈内存和调度资源。典型场景:向无接收者的 channel 发送(或对 nil channel 收发)永久阻塞;for-select 循环缺少退出分支;HTTP 客户端未设超时导致读阻塞;锁使用不当永久等锁;长循环里 time.After 堆积 timer。

排查手段:生产环境接入 net/http/pprof,观察 /debug/pprof/goroutine 的数量曲线和完整堆栈,泄漏的 goroutine 会呈现大量相同调用栈;监控 runtime.NumGoroutine 的趋势;测试中可用 uber 的 goleak 库在用例结束时校验 goroutine 是否归零。

防范模式:每个 goroutine 都要有明确退出路径,用 context 或 quit channel 传递取消信号;发送遵循'要么缓冲足够,要么确认有接收者';IO 一律设 deadline。

func run(ctx context.Context, ch chan<- int) {
    for {
        select {
        case <-ctx.Done():
            return // 保证可退出
        case ch <- work():
        }
    }
}

追问方向:泄漏与内存泄漏的叠加效应、如何给存量代码补退出路径。