Go 1.27 新增 Goroutine Leak 检测
Goroutine Leak Profiles

Go 语言的并发特性强大易用,但也常导致 Goroutine 泄漏,进而拖慢性能。过去这类问题在单元测试中难以复现,生产环境更是难以察觉。Go 1.27 推出了全新的 Goroutine Leak Profiler,能精准定位因 channel 或 sync 包原语永久阻塞导致的泄漏。该工具基于垃圾回收机制改进,无需人工分析即可自动识别泄漏点,且误报率极低。虽然它目前仅覆盖部分阻塞场景,但已能解决大量实际生产问题,是 Go 开发者调试并发代码的利器。
如果 Goroutine 被某个没有其他 Goroutine 可访问的并发原语阻塞,那么它显然已经泄漏。
- sethammons
通用原则:在调用 goroutine 之前,务必清楚它将如何关闭。
- deathanatos
我主要来自其他语言背景,所以花了好一会儿才搞懂各种 bug 是怎么回事。
• 默认情况下,channel 是“无缓冲”的,这意味着发送操作必须等待一个接收操作才能真正完成,并会一直阻塞直到发生接收。添加缓冲区可以避免阻塞,让 goroutine 继续运行(最终退出,从而不会泄漏)……前提是缓冲区足够大。
• 据我所知,channel 似乎无法感知接收端是否已经消失,即使没有接收者,它也会无限期地阻塞。(我认为发送端和接收端使用的是同一个“chan”对象,两者没有区别。因此,这个单一对象永远不会被 GC 回收。)
• goroutine 本身不会被 GC 回收。(而且代码也无法/不能持有对 goroutine 的引用或句柄,因为没有“join”原语。)