go是帶內存自動回收的特性,所以內存通常不會泄漏。可是Goroutine確存在泄漏的狀況,同時泄漏的Goroutine引用的內存一樣沒法被回收。函數
下面的程序中後臺Goroutine向管道輸入天然數序列,main函數中輸出序列。可是當break跳出for循環的時候,後臺Goroutine就處於沒法被回收的狀態了。blog
func main() { ch := func() <-chan int { ch := make(chan int) go func() { for i := 0; ; i++ { ch <- i } } () return ch }() for v := range ch { fmt.Println(v) if v == 5 { break } } }
咱們能夠經過context包來避免這個問題:內存
func main() { ctx, cancel := context.WithCancel(context.Background()) ch := func(ctx context.Context) <-chan int { ch := make(chan int) go func() { for i := 0; ; i++ { select { case <- ctx.Done(): return case ch <- i: } } } () return ch }(ctx) for v := range ch { fmt.Println(v) if v == 5 { cancel() break } } }
當main函數在break跳出循環時,經過調用cancel()來通知後臺Goroutine退出,這樣就避免了Goroutine的泄漏。it