性能调优pprof实战 | 青训营

196 阅读3分钟

性能调优pprof实战

pprof是Go语言运行时提供的可视化性能分析工具,可以用来分析程序的CPU、内存等使用情况。在我们需要实践的项目中有提前加入一些冗余代码,产生很大的性能问题,运行后会占用大部分CPU和内存空间。

排查CPU指标

打开资源管理器查看项目CPU占用,使用go tool pprof获取最近10秒的数据

go tool pprof http://localhost:6060/debug/pprof/profile?seconds=10

通过seconds参数可以限定我们获取数据的时间,使用TopN命令可以查看占用资源最多的前N个函数,在数据图中我们可以看到,Eat函数占用较大的CPU时间。

使用命令list Eat,根据指定的正则表达式查找代码,使用web命令,查看可视化调用图,可以发现源代码中存在冗余的for循环占用了很多CPU,我们将该行代码进行注释,然后再运行可以发现CPU占用已经降低。

排查堆内存指标

我们发现内存占用很多GB,在控制台输入与之前类似的命令,不过需要将后缀改为heap,打开浏览器进入并查看TopN的数据,从图中我们发现Steal函数占用空间很多。

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

查看源代码可以发现Live函数调用了Steal函数,而Steal函数中不断扩展切片,从而导致内存占用 注释该代码即可发现内存占用的问题已经解决。

排查协程指标

再次进入浏览器查看指标,可以发现goroutine有19个,也可能导致内存泄露。

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

其中Wolf.Drink函数间接占用了大部分的协程,我们可以通过火焰图来寻找CPU占用时间最多的块,查看源代码可以发现,该函数中每创建一个协程就会sleep一段时间,从而阻塞CPU和内存资源的分配。将下列代码注释后,源程序的运行性能又得到了提高。

排查锁指标

在网页中进入锁排查部分

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

我们可以发现Wolf.Howl函数中存在一个匿名函数func1,且该函数中包含一个延迟1秒和一个锁,这也导致了资源释放存在延迟,从而导致运行性能下降

排查阻塞指标

在网页中进入阻塞排查部分

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

我们可以发现一个由Cat.Pee函数调用的函数,它在1秒内占用了所有的CPU。查看源代码可以发现,该函数在指定时间后发送一个值,阻塞等待完成,导致运行性能显著下降。