【go】time.after内存泄漏
- 软件开发
- 2025-09-13 21:24:02

func worker() { select { case <-c: // ... do some stuff case <-time.After(30 *time.Second): return } }
它创建了一个计时器,但返回的只是计时器关联的通道 如果不从返回的通道中接收值,即使超时发生后,计时器也不会被垃圾回收 这会导致计时器泄漏,特别是在循环中使用时会创建大量无法及时回收的计时器
改进方法 调用defer 进行stop func worker() { timer := time.NewTimer(30 * time.Second) defer timer.Stop() // 确保定时器被清理 select { case <-c: // ... do some stuff case <-timer.C: return } } Kubernetes中的改进方式: 重用定时器在maxinflight.go的代码中,使用了wait.Until函数,其内部已经正确处理了定时器的创建和清理: (接上篇 maxinflight.go 的源码略读)
func Until(f func(), period time.Duration, stopCh <-chan struct{}) { JitterUntil(f, period, 0.0, true, stopCh) } func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) { var t *time.Timer var sawTimeout bool for { select { case <-stopCh: return default: } jitteredPeriod := period if jitterFactor > 0.0 { jitteredPeriod = Jitter(period, jitterFactor) } if !sliding { t = resetOrReuseTimer(t, jitteredPeriod, sawTimeout) } func() { f() }() if sliding { t = resetOrReuseTimer(t, jitteredPeriod, sawTimeout) } // 注意这里重用了定时器 select { case <-stopCh: return case <-t.C: sawTimeout = true } } }【go】time.after内存泄漏由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【go】time.after内存泄漏”