pprof性能调优实战 | 青训营笔记

74 阅读2分钟

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

前几天在后端青训营的课上学了如何用pprof分析程序的性能瓶颈,感觉非常受用。正好之后写大项目的时候也能用的上,因此写文章分享一下如何利用pprof进行性能调优。

启动pprof网页端

首先下载并导入pprof包。这个包在初始化的时候会自动绑定http.Handler函数路由,我们只需要在某个端口上启动http服务器即可。这里我们以这个“炸弹”程序为例,这个程序里有很多典型的性能瓶颈,适合拿来练手。该程序在6060端口上启动web服务,使用浏览器打开http://localhost:6060/debug/pprof/

pprof首页

里面详细列出了内存分配(allocs)、阻塞(block)、goroutine等可能会影响性能的指标,可以大致帮助判断程序的性能瓶颈。

点进去可以查看具体是哪里“贡献”了这些指标,但是里面事无巨细的列出了所有地方,包括运行时和一些别的库,因此可能不是很直观。

图片.png

使用pprof命令行工具分析

go语言自带go tool pprof命令来分析性能信息,这个性能信息既可以是程序运行后导出的,也可以从刚才的web服务中获取,这里为了方便就使用刚才建好的web服务。因此输入go tool pprof http://localhost:6060/debug/pprof/profile命令,然后输入top,排查cpu占用问题。

图片.png

很明显,占用率排在第一位的是tiger.(*Tiger).Eat函数。如果你懒得翻代码的话,可以用list Eat命令显示运行的Eat函数。

图片.png

列出来的除了Tigereat函数,还显示了Dog等的。我们找到Tiger,发现里面有个死循环,这就是问题根本了。

接下来排除内存问题,这次重新运行go tool pprof http://localhost:6060/debug/pprof/heap命令,多了个/heap,毕竟动态分配的内存都在堆里。

图片.png

flat表示该函数自己使用内存占比,cum则加上了其调用的函数的。看得出来这次是mouse.(*Mouse).Steal占用了最多内存,看看它的代码长什么样。

图片.png

它一共申请了1G的内存。

类似的,查看累加申请内存最多的可以用go tool pprof http://localhost:6060/debug/pprof/allocs, 创建goroutine最多的可以用go tool pprof http://localhost:6060/debug/pprof/goroutine等,此处不再赘述。