[Golang] Leaks In Goroutine And Debug Resource
Ví Dụ Đơn Giản
func leak() {
doWork := func(strings <-chan string) <-chan interface{} {
completed := make(chan interface{})
go func() {
defer fmt.Println("doWork exited.")
defer close(completed)
for s := range strings {
// Do something interesting
fmt.Println(s)
}
}()
fmt.Println("end function doWork")
return completed
}
fmt.Println("dowork")
doWork(nil)
// Perhaps more work is done here
fmt.Println("Done.")
}
- trong func doWork với parameter là một chan string.
- func sẽ leak vì string channel là một giá trị nil. Có nghĩa là goroutine này không clear tài nguyên, không stop func.
- ví dụ trên có lẽ là cực kì ngắn, nhưng trong thực tế thì func sẽ tồn tại trong lifetime và ảnh hưởng đến tài nguyên của chương trình.
Debug Resource
Cài package
- cài package:
apt-get install graphviz gv
(debian) orbrew install graphviz
(mac) - cài pprof:
go get -u github.com/google/pprof
- import pprof:
import _ "net/http/pprof"
- add server:
pprof
source
package main
import (
"fmt"
"net/http"
_ "net/http/pprof"
"os"
"os/signal"
"syscall"
)
func leak() {
doWork := func(strings <-chan string) <-chan interface{} {
completed := make(chan interface{})
go func() {
defer func() {
fmt.Println("doWork exited.")
}()
defer func() {
close(completed)
}()
for s := range strings {
// Do something interesting
fmt.Println(s)
}
}()
fmt.Println("end function doWork")
return completed
}
fmt.Println("dowork")
doWork(nil)
// Perhaps more work is done here
fmt.Println("Done.")
}
func main() {
leak()
leak()
leak()
go func() {
http.ListenAndServe(":1234", nil)
}()
//
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
done := make(chan bool, 1)
go func() {
<-sigs
done <- true
}()
<-done
}
- trong func main, gọi 3 hàm leak() -> trong lifetime sẽ có 3 goroutine bị leak
- start server với port 1234
- sau khi start server, mở một terminal khác
go tool pprof http://localhost:1234/debug/pprof/goroutine
và enterpng
- sẽ có kết quả
Generating report in profile001.png
- Kết quả trong hình sử dụng pprof thì sẽ có 3 leak.
Video https://www.youtube.com/watch?v=e1Aa4d90nzk
Source https://github.com/ducnpdev/open-dev/blob/master/concurrency/leak.go
Liên Hệ
- facebook: https://www.facebook.com/phucducdev/
- group: https://www.facebook.com/groups/575250507328049
- gmail: ducnp09081998@gmail.com
- linkedin: https://www.linkedin.com/in/phucducktpm/
- hashnode: https://hashnode.com/@OpenDev
- telegram: https://t.me/OpenDevGolang
All rights reserved