如何使用go tool pprof
pprof是golang内置的性能调优工具,可以分析:
- 内存使用情况
- CPU使用情况
- go routine阻塞情况
- 互斥锁使用情况
等。同时,1.11版本以后,它集成了go-torch的功能,可以将这些profile可视化,让结果更直观。
如何生成profile
有三种方式可以生成profile,具体可以参考runtime/pprof的官方文档。
运行测试时生成
go test集成了profile功能,它提供了一些选项,可以方便的生成profile文件。
go test -cpuprofile cpu.prof -memprofile mem.prof -bench .
使用runtime/pprof库来生成
对于独立的可执行程序,如果我们想生成profile文件,可以添加一些代码调用runtime/pprof库来生成他们,官方文档的例子如下。
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal("could not create CPU profile: ", err)
}
defer f.Close()
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("could not start CPU profile: ", err)
}
defer pprof.StopCPUProfile()
}
// ... rest of the program ...
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal("could not create memory profile: ", err)
}
defer f.Close()
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("could not write memory profile: ", err)
}
}
}
导入net/http/pprof包
还有一种可以动态获取profile数据的方式是在代码中导入net/http/pprof这个包。它会注册一个HTTP handler,然后我们就可以通过HTTP调用的方式来动态的获取profile。
import _ "net/http/pprof"
如何分析profile
有了profile文件,我们就可以使用go提供的命令行工具来分析他们。
go tool pprof cpu.prof
这种方式需要我们很熟悉pprof这个工具,需要熟练使用它的各个选项,并且很多数据呈现在命令行,不是很直观。当然,它有一个子命令web,它会打开浏览器,以图像的方式来呈现profile数据。
pprof还可以直接启动一个HTTP server来对外服务profile数据,它有很多丰富的展示选项,除了默认的图形化的展示以外,还可以展示火焰图。使用它可以让我们快速、直观的浏览profile数据。
go tool pprof -http=":8081" [binary] [profile]