注意:部分内容摘自 深入探讨 goroutine 泄漏和避免它们的最佳实践 - 知乎
- // 例1
-
- func newgoroutine(dataChan chan
) { - data := makeNetworkCall()
- dataChan <- data // 阻塞住了
- return
- }
-
- func main() {
- dataChan := make(chan
) - go newgoroutine(dataChan)
- return
- }
-
-
- // 例2
-
- func newgoroutine(dataChan chan
) { - data := <- dataChan // 阻塞住了
- return
- }
-
- func main() {
- dataChan := make(chan
) - go newgoroutine(dataChan)
- data, err := makeNetworkCall()
- if err != nil {
- return
- }
- dataChan <- data
- return
- }
(1)通过goroutin监控
(2)服务器启动时使用禁用垃圾收集器 debug.SetGCPercent(-1),然后在运行代码中打印 API 启动前和执行后正在运行的 goroutines 的数量,如果服务在前后返回不同数量的 Goroutines,那么该流程中存在泄漏。
- func ApplyPromo() {
- fmt.Println(runtime.NumGoroutine())
- defer fmt.Println(runtime.NumGoroutine()
- }
例如为避免上面两个case,可以将无缓冲区的channel改为有缓冲区的channel。