这是我参与「第五届青训营 」伴学笔记创作活动的第 三 天
实践Go开发性能调优杀器——pprof;
实践准备
实践源码:github.com/wolfogre/go… | Git Clone github.com/wolfogre/go…
可视化工具:graphviz,安装建议:记得勾选添加环境变量到PATH
实践使用go tool pprof命令排查问题,主要排查实践内容如下:
- 排查CPU高占用
- 排查内存高占用
- 排查GC频繁
- 排查协程泄露
- 排查锁竞争
- 排查阻塞操作
克隆实践源码后,使用go build命令编译以下程序,./go-pprof-practice运行程序。
排查CPU高占用
保持程序运行,在命令行输入go tool pprof http://localhost:6060/debug/pprof/profile命令。
看到上面的界面时就就进入了pprof的控制台了,这时使用
top命令看一下导致当前CPU高占用的罪魁祸首是谁...
可以清楚的看到
github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Eat造成了CPU的高占用,再使用list Eat命令,查看导致CPU高占用问题代码的具体位置。
func (t *Tiger) Eat() {
log.Println(t.Name(), "eat")
loop := 10000000000
for i := 0; i < loop; i++ {
// do nothing
}
}
这样子就定位到了上述的方法块了,不难看出导致CPU高占用的原因在于进行这个百亿的空循环,接下来只需要对Eat这个方法进行分析优化(这儿将for循环注释)就可以解决导致当前CPU高占用的问题。
在安装了graphviz后,排查问题不仅可以像上述使用top、list命令进行分析排查,也可以使用web命令生成.svg文件进行可视化排查,在控制台输入web:
可以看到在图中的Eat方法的框被特意框选出来。至此就完成了第一步排查:CPU高占用。接下来的排查内容基本与此大同小异,基本流程就是使用go tool pprof命令 -> 使用top命令(定位问题代码) -> 使用list XXX命令(定位具体问题代码列表)。
排查内存高占用
在将CPU高占用代码注释后,执行go build再使用./go-pprof-practice命令运行程序。
操作步骤跟排查CPU高占用相似:
- 第一步:
go tool pprof http://localhost:6060/debug/pprof/heap命令,对堆内存进行pprof分析 - 第二步:
top命令,显示go-pprof-practice堆内存信息 - 第三步:
list XXX命令,显示XXX下的具体代码块 - 可选步骤:
web,通过.svg图像文件进行问题定位
首先在控制台使用go tool pprof <http://localhost:6060/debug/pprof/heap>,然后使用top命令查看协程的堆内存使用信息:
这样子就可以定位到github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Steal导致了堆内存的高占用问题了,再输入list Steal命令就可以定位到出现问题的具体方法代码。
func (m *Mouse) Steal() {
log.Println(m.Name(), "steal")
max := constant.Gi
for len(m.buffer)*constant.Mi < max {
//一直向buffer里添加1MB的数组,使得内存得不到释放
m.buffer = append(m.buffer, [constant.Mi]byte{})
}
}
就这样,轻松定位到了这只偷内存的老鼠了。
使用web命令可以看到.svg图形也定位到了Steal方法,并将其用大红框框选出来了:
接下来的排查优化操作步骤大差不差,就不在一一赘述了,在总结部分直接贴出各个排查部分的go tool pporf命令。
排查GC频繁
这一步我遇到一个暂未解决的问题,就是使用GODEBUG=gctrace=1 ./go-pprof-practice | grep gc命令时报以下异常:
尝试使用网上的解决办法:设置环境变量
$env:Path [System.Environment]::GetEnvironmentVariable("Path","Machine")
但是并未解决...希望有遇到此问题大佬能帮忙解惑。
go tool pprof命令
- 排查CPU高占用:
go tool pprof http://localhost:6060/debug/pprof/profile - 排查内存高占用:
go tool pprof http://localhost:6060/debug/pprof/heap - 排查GC频繁:
go tool pprof http://localhost:6060/debug/pprof/allocs - 排查协程泄露:
go tool pprof http://localhost:6060/debug/pprof/goroutine - 排查锁竞争:
go tool pprof http://localhost:6060/debug/pprof/mutex - 排查阻塞操作:
go tool pprof http://localhost:6060/debug/pprof/block
总的来说对Go程序使用pprof进行性能调优大致有以下的步骤:
- 第一步:使用
go tool pprof命令,对不同的资源场景进行查看 - 第二步:使用
top命令,查看当前资源场景下的高占用协程信息 - 第三步:使用
list XXX命令,查看具体的问题代码 - 可选步骤:使用
web命令,可视化的方式进行问题分析