简介与前言
本文章是高质量编程与性能调优实战的第二部分,主要内容是pprof工具的使用与实战,并对经典案例进行调优。
性能优化、调优原则:
- 要依靠数据而不是猜测
- 要定位最大瓶颈而不是细枝末叶
- 不要过早优化
- 不要过度优化
工具与项目简介
性能分析工具pprof
pprof是一个性能分析工具,它可以生成类似火焰图、堆栈图、内存分析图等。Go在1.11版本后在它自带的工具集go tool里内置了pprof工具来分析由pprof库生成的数据文件。Go在语言层面集成了profile采样工具,在程序运行过程中可以获取cpu、heap、block、traces等执行信息pprof工具可以帮助开发人员快速定位程序中的性能瓶颈,从而优化程序性能。它支持多种语言,包括Go、C++、Java、Python等。pprof工具可以通过命令行或Web界面进行操作,提供了丰富的可视化选项,方便开发人员查看和分析性能数据。
项目简介
搭建pprof实践项目,这里使用的是github上一个开源项目,这个项目提前埋入了一些炸弹代码,产生可观测的性能问题,运行该项目会占用1CPU核心和超过GB的内存。
开源项目地址:github.com/wolfogre/go…
项目运行
在运行项目中的 main.go 文件后,可以打开web浏览器,在地址栏输入http://localhost:6060/debug/pprof
,结果如下图所示
pprof包内调用runtime
包中函数以获取各种运行时信息,其包含如下分析指标。
- allocs: 过去所有内存分配的样本
- block: 导致同步原语阻塞的堆栈跟踪
- cmdline: 当前程序的命令行调用,与/proc/中的 cmdline相同
- goroutine: 当前所有goroutine的堆栈跟踪
- heap: A活动对象的内存分配的采样。您可以指定gc GET参数以在获取堆样本之前运行GC。
- mutex: 竞争互斥体持有人的堆栈痕迹
- profile: CPU配置文件。您可以在秒GET参数中指定持续时间。获取概要文件后,使用go tool pprof命令调查概要文件。
- threadcreate: 导致创建新OS线程的堆栈跟踪
- trace: 当前程序执行的痕迹。您可以在秒GET参数中指定持续时间。获取跟踪文件后,请使用go工具trace命令调查跟踪。
CPU占用分析
分析cpu占用时使用pprof的命令行进行分析。
在终端输入命令 go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=50"
一段时间后返回界面。
top
输入top
命令,用于查看占用资源最多的函数
flat
: 当前函数本身的执行耗时flat%
:flat
占CPU
总时间的比例sum%
: 上面每一行的flat%
总和cum
: 当前函数本身加上其周期函数的总耗时cum%
:cum
占CPU
总时间的比例
通过top
命令,得出Eat
函数占用CPU
时间最长,使用list
命令定位到代码的具体行。
list
list
命令返回结果如图
可以清楚的发现,loop被定义的太大导致该函数执行时间太长,将loop进行修改。
修改后,再次运行
函数占用率与运行时间恢复了正常。
内存占用分析
经过修改后,程序CPU占用过高的问题已经解决,但是内存使用还是很高。
输入web
命令输出可视化的内存占用图,发现Mouse的内存占用率最高。
我们可以使用web分析,而不是使用命令行提高效率。
输入命令go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
下图与list
命令结果相同
点击source可以查看占用最多的代码,并进行修改。
在这里我首先采用了注释的方法,发现程序无法正常运行,在constant中定义类常量Mi为1024*1024,将其改为Ki即可。最终减少了内存的占用。