pprof实践 | 青训营笔记

153 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 三 天

实践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命令。

image.png 看到上面的界面时就就进入了pprof的控制台了,这时使用top命令看一下导致当前CPU高占用的罪魁祸首是谁...

屏幕截图 2023-01-17 190905.png 可以清楚的看到github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Eat造成了CPU的高占用,再使用list Eat命令,查看导致CPU高占用问题代码的具体位置。

屏幕截图 2023-01-17 203804.png

func (t *Tiger) Eat() {
    log.Println(t.Name(), "eat")
    loop := 10000000000
    for i := 0; i < loop; i++ {
        // do nothing
    }
}

这样子就定位到了上述的方法块了,不难看出导致CPU高占用的原因在于进行这个百亿的空循环,接下来只需要对Eat这个方法进行分析优化(这儿将for循环注释)就可以解决导致当前CPU高占用的问题。

在安装了graphviz后,排查问题不仅可以像上述使用toplist命令进行分析排查,也可以使用web命令生成.svg文件进行可视化排查,在控制台输入web

pprof001.svg

可以看到在图中的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命令查看协程的堆内存使用信息:

屏幕截图 2023-01-17 191429.png

这样子就可以定位到github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Steal导致了堆内存的高占用问题了,再输入list Steal命令就可以定位到出现问题的具体方法代码。

屏幕截图 2023-01-17 191528.png

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方法,并将其用大红框框选出来了:

pprof002.svg

接下来的排查优化操作步骤大差不差,就不在一一赘述了,在总结部分直接贴出各个排查部分的go tool pporf命令。

排查GC频繁

这一步我遇到一个暂未解决的问题,就是使用GODEBUG=gctrace=1 ./go-pprof-practice | grep gc命令时报以下异常:

image-20230117211920404.png

尝试使用网上的解决办法:设置环境变量 $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命令,可视化的方式进行问题分析