打开这个网页http://localhost:6060/debug/pprof/,注意在打开这个网页之前需要运行你的项目
第一个问题,cpu占用问题,用于解决程序的cpu占用时间过长
在打开网页的前提下打开控制台输入以下命令
go tool pprof http://localhost:6060/debug/pprof/profile
等待之后出现一个可交互终端
在控制台输入topN , N表示查看函数的个数
该方法会显示占用cpu最高的前n个函数显示出来,不加n默认显示10个
容易发现github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Eat进程占的内存最多,问题出在这里
输入list Eat来看问题代码的位置
从24行到27行,容易看见这个循环被进行了10000000000次,很明显就是这个循环占用了太多的cpu时间
在编译器中找到这个代码,修改它
重启cmd再重新进入一边以更新数据,输入top
Cpu数据回复正常,问题解决
从任务管理器可以看出这时虽然cpu的占用已经降下来了,但是内存的占用率仍然很高
我们输入这串命令go tool pprof http://localhost:6060/debug/pprof/heap
然后再输入top
可以看到这次内存占用最高的是一个steal程序
输入list Steal
发现steal函数占了1.2gb的内存,这对一个仅在控制台打印信息的函数是不正常的
发现60行有个数组一直向m添加1mb的数组,直到1gb为止,这也是导致内存占用过高的原因
这里我们可以选择用一个插件来图形化显示调用栈信息,在这里下载适合你操作系统的版本
安装完后在控制台终端输入web,然后他会产生一个svg文件,需要你自己设置用浏览器打开。
显示出来长这样。
容易看到steal函数是最大的那个框,表示它就是占内存最多的那个
同时也能看到具体占了1.2gb内存,是它自己不断向数组添加直到1gb数组的结果
修改相关代码
现在整个进程只占了48Mb的内存,内存运行正常
现在排查频繁的内存回收问题
为了获取程序运行过程中 GC 日志,我们需要先退出炸弹程序,再在重新启动前赋予一个环境变量,同时为了避免其他日志的干扰,使用 grep 筛选出 GC 日志查看:
GODEBUG=gctrace=1 ./go-pprof-practice | grep gc
日志如下:
从日志看出每隔3秒就给进程就申请16mb的内存然后在释放
我们在控制台输入go tool pprof http://localhost:6060/debug/pprof/allocs
向上面一样输入top list ... web
找到占资源较高的代码
第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