性能分析工具pprof实战|青训营

185 阅读5分钟

先下载源码github.com/wolfogre/go…

打开这个网页http://localhost:6060/debug/pprof/,注意在打开这个网页之前需要运行你的项目

第一个问题,cpu占用问题,用于解决程序的cpu占用时间过长

 

在打开网页的前提下打开控制台输入以下命令

go tool pprof http://localhost:6060/debug/pprof/profile

等待之后出现一个可交互终端

转存失败,建议直接上传图片文件 

图片27.png 在控制台输入topN , N表示查看函数的个数

该方法会显示占用cpu最高的前n个函数显示出来,不加n默认显示10个

 

转存失败,建议直接上传图片文件 

28.png 容易发现github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Eat进程占的内存最多,问题出在这里

输入list Eat来看问题代码的位置

转存失败,建议直接上传图片文件 

29.png 从24行到27行,容易看见这个循环被进行了10000000000次,很明显就是这个循环占用了太多的cpu时间

转存失败,建议直接上传图片文件 

30.png 在编译器中找到这个代码,修改它

重启cmd再重新进入一边以更新数据,输入top

转存失败,建议直接上传图片文件 

31.png Cpu数据回复正常,问题解决

从任务管理器可以看出这时虽然cpu的占用已经降下来了,但是内存的占用率仍然很高

我们输入这串命令go tool pprof http://localhost:6060/debug/pprof/heap

然后再输入top

可以看到这次内存占用最高的是一个steal程序

输入list Steal

转存失败,建议直接上传图片文件 

32.png 发现steal函数占了1.2gb的内存,这对一个仅在控制台打印信息的函数是不正常的

发现60行有个数组一直向m添加1mb的数组,直到1gb为止,这也是导致内存占用过高的原因

这里我们可以选择用一个插件来图形化显示调用栈信息,在这里下载适合你操作系统的版本

Download | Graphviz

安装完后在控制台终端输入web,然后他会产生一个svg文件,需要你自己设置用浏览器打开。

转存失败,建议直接上传图片文件 

33.png 显示出来长这样。

容易看到steal函数是最大的那个框,表示它就是占内存最多的那个

同时也能看到具体占了1.2gb内存,是它自己不断向数组添加直到1gb数组的结果

修改相关代码

转存失败,建议直接上传图片文件 

34.png 现在整个进程只占了48Mb的内存,内存运行正常

现在排查频繁的内存回收问题

为了获取程序运行过程中 GC 日志,我们需要先退出炸弹程序,再在重新启动前赋予一个环境变量,同时为了避免其他日志的干扰,使用 grep 筛选出 GC 日志查看:

GODEBUG=gctrace=1 ./go-pprof-practice | grep gc

日志如下:

 

转存失败,建议直接上传图片文件  35.png 从日志看出每隔3秒就给进程就申请16mb的内存然后在释放

我们在控制台输入go tool pprof http://localhost:6060/debug/pprof/allocs

向上面一样输入top list ... web

找到占资源较高的代码

转存失败,建议直接上传图片文件 

36.png 第43行看到dog。Run在不停申请16mb的内存

修改掉问题代码

问题解决

关于火焰图

 火焰图就像是给一个软件系统拍的 X 光照片,可以很自然地把时间和空间两个维度上的信息融合在一张图上,以非常直观的形式展现出来,从而反映系统在性能方面的很多定量的统计规律。

y 轴表示调用栈, 每一层都是一个函数。调用栈越深, 火焰就越高, 顶部就是采样时正在执行的函数, 下方都是它的父函数。

x 轴表示抽样数, 如果一个函数在 x 轴占据的宽度越宽, 就表示它被抽到的次数多, 即执行的时间长,说明它是瓶颈原因的可能性就越大。注意, x 轴不代表时间, 而是所有的调用栈合并后, 按字母顺序排列的。

无意义的事情:横向先后顺序是为了聚合,跟函数间依赖或调用关系无关;火焰图各种颜色是为方便区分,本身不具有特殊含义。

其他的采样方式也可以使用火焰图, on-cpu 火焰图横轴是指 cpu 占用时间,off-cpu 火焰图横轴则代表阻塞时间。不同类型火焰图适合优化的场景不同,比如 on-cpu 火焰图适合分析 cpu 占用高的问题函数,off-cpu 火焰图适合解决阻塞和锁抢占问题。

火焰图可以理解成他的顶端温度最高。顶部就是正在执行的函数
火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶山",就表示该函数可能存在性能问题。

火焰图的生成

安装go-torch
go get github.com/uber/go-torch在cmd输入

安装 FlameGraph
cd WORK_PATH && git clone [https://github.com/brendangregg/FlameGraph.git](https://link.jianshu.com/?t=https://github.com/brendangregg/FlameGraph.git) export PATH=PATH:$WORK_PATH/FlameGraph-master

安装graphviz
yum install graphviz(CentOS, Redhat)

生成cpu火焰图go-torch -u http://localhost:8888/debug/pprof/ -p > profile-local.svg

生成内存火焰图:
go-torch -u http://localhost:8888/debug/pprof/heap -p > heap-local.svg