
Go 性能分析
pprof、tarce 是用于可视化和分析性能分析数据的工具。
pprof
runtime/pprof
介绍
采集程序运行数据进行性能分析,一般用于后台工具型应用,这种应用运行一段时间就结束。
使用方法
go test -cpuprofile cpu.prof -memprofile mem.prof -v
package main
import (
"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() // error handling omitted for example
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() // error handling omitted for example
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("could not write memory profile: ", err)
}
}
}
分析
使用 go tool pprof
命令对具体文件分析
net/http/pprof
介绍
对 runtime/pprof 的二次封装,一般是服务型应用。比如 web server ,它一直运行。这个包对提供的 http 服务进行数据采集分析。
使用方法
package main
import (
_ "net/http/pprof"
"net/http"
)
func main() {
http.ListenAndServe(":8000", nil)
}
分析
运行程序之后,在浏览器中输入:http://localhost:8000/debug/pprof/,查看服务运行情况。
- allocs: 过去所有内存抽样情况
- block: 同步阻塞时程序栈跟踪的一些情况
- cmdline: 显示程序启动命令及参数
- goroutine: 所有当前 goroutine 的堆栈跟踪
- heap: 活动对象的内存分配情况
- mutex: 锁争用情况的采样信息
- profile: cpu 占用情况的采集信息
- threadcreate: 系统线程创建情况的采样信息
- trace: 程序执行的追踪情况
# 下载 cpu profile,默认从当前开始收集 30s 的 cpu 使用情况,需要等待 30s
go tool pprof http://localhost:8000/debug/pprof/profile
# wait 120s
go tool pprofhttp://localhost:8000/debug/pprof/profile?seconds=120
# 下载 heap profile
go tool pprof http://localhost:8000/debug/pprof/heap
# 下载 goroutine profile
go tool pprof http://localhost:8000/debug/pprof/goroutine
# 下载 block profile
go tool pprof http://localhost:8000/debug/pprof/block
# 下载 mutex profile
go tool pprof http://localhost:8000/debug/pprof/mutex
常用命令
top
top 默认查看程序中占用CPU前10位的函数
- flat:当前函数占用CPU的耗时
- flat%:当前函数占用CPU的耗时百分比
- sum%:函数占用CPU的耗时累计百分比
- cum:当前函数加上调用当前函数的函数占用CPU的总耗时
- cum%:当前函数加上调用当前函数的函数占用CPU的总耗时百分比
- 最后一列:函数名称
list
我们还可以使用 list 函数名命令查看具体的函数分析,例如执行 list gopark 查看我们编写的函数的详细分析。
pdf 可以生成可视化pdf文件
trace
介绍
trace
能够辅助我们跟踪程序的执行情况,进一步方便我们排查问题,往往配合 pprof
使用。
使用方法
go test -trace trace.pprof -v
package main
import (
"context"
"fmt"
"os"
"runtime/trace"
"sync"
)
var (
wg sync.WaitGroup = sync.WaitGroup{}
ctx context.Context = context.TODO()
)
func main() {
f, err := os.Create("trace.pprof")
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
if err := trace.Start(f); err != nil {
fmt.Println(err)
return
}
defer trace.Stop()
// trace.Log(ctx, "Log Of Sum", "sum")
for i := 0; i < 8; i++ {
wg.Add(1)
go sum(i)
}
wg.Wait()
}
func sum(n int) {
var ans int
r := trace.StartRegion(ctx, fmt.Sprintf("sum %d", n))
for i := 0; i < 100; i++ {
ans += i
}
defer wg.Done()
defer r.End()
}
分析
- View trace:查看跟踪
- Goroutine analysis:Goroutine 分析
- Network blocking profile:网络阻塞概况
- Synchronization blocking profile:同步阻塞概况
- Syscall blocking profile:系统调用阻塞概况
- Scheduler latency profile:调度延迟概况
- User defined tasks:用户自定义任务
- User defined regions:用户自定义区域
- Minimum mutator utilization:最低 Mutator 利用率