Go语言性能分析工具pprof的使用 | 青训营笔记

255 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。

pprof 是 Go 语言中分析程序运行性能的工具,它能提供各种性能数据:

类型描述
allocs内存分配情况的采样信息
blocks阻塞操作情况的采样信息
cmdline显示程序启动命令及参数
goroutine显示所有协程的堆栈信息
heap堆上内存使用情况的采样信息
profileCPU 占用情况的采样信息
threadcreate系统线程创建情况的采样信息

其中allocs 和 heap 采样的信息一致,不过前者是所有对象的内存分配,而 heap 则是活跃对象的内存分配。

我们可以通过 报告生成Web 可视化界面交互式终端 三种方式来使用 pprof。这里我使用 wolfogre/go-pprof-practice: go pprof practice. (github.com) 项目结合Web 可视化界面方法介绍pprof工具的基本使用方法。

proflie | CPU

首先,启动项目'main.go'。可以看到以下输出:

2022/05/12 20:01:24 dog.go:38: dog pee
2022/05/12 20:01:24 dog.go:42: dog run
2022/05/12 20:01:24 dog.go:47: dog howl
2022/05/12 20:01:24 wolf.go:27: wolf eat
2022/05/12 20:01:24 wolf.go:31: wolf drink
2022/05/12 20:01:24 wolf.go:40: wolf shit
...

此时项目已经启动成功,pprof 工具的入口会被配置为 http://{host}:6060/debug/pprof, 访问该网址会看到以下信息。

image.png

现在可以对系统运行情况进行采样,在终端中执行

go tool  pprof -http :8080 http://{host}:6060/debug/pprof/profile?seconds=10

,采样接下来10s的系统运行信息。等待终端输出以下信息后说明采样完成

PS D:\GolandProjects\go-pprof-practice> go tool pprof -http :8080 http://localhost:6060/debug/pprof/profile?seconds=10  
Fetching profile over HTTP from http://localhost:6060/debug/pprof/profile?seconds=10
Saved profile in C:\Users\wobuh\pprof\pprof.samples.cpu.004.pb.gz
Serving web UI on http://localhost:8080

此时打开http://{host}:8080/ui可以看到采样结果

image.png 通过默认显示的框图可以很直接地发现 tigerEat 方法占用了大量 CPU 时间,接下来,让我们通过 Source 视图定位消耗大量 CPU 时间的代码。

image.png

随后改正该代码即可。

heap | 内存分配

在终端中执行

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

对进程的堆信息进行采样,此时不需要提供采样时长信息,因为对内存的采样的时间段是从进程运行开始到执行采样命令的所有时间。 采样完成后,打开 ui 界面,可以看到左上角的 SAMPLE 下拉菜单,其中有四个选项,分别代表分配的对象数、分配的内存数、在使用的对象数、在使用的内存数。

image.png 为了使我们的分析更加准确,我们选择分配的内存数,因为这个选项包含了以及被 gc 回收掉的内存。

image.png

在这个视图可以清晰地找到消耗大量内存的对象方法。随后,我们定位源码位置。

image.png

image.png 现在我们可以对代码进行改善

Goroutine

在终端中执行

go tool pprof -http :8080 http://localhost:6060/debug/pprof/goroutine?seconds=10

goroutine数进行采样。采样结果如下图所示

image.png 得到采样结果后,定位问题源代码。

image.png

Mutex | 锁竞争

在终端中输入

go tool pprof -http :8080 http://localhost:6060/debug/pprof/mutex?seconds=10

采样 Mutex 锁竞争信息。可以看到采样结果如下。

image.png 接下来定位源码位置。

image.png

Block | 阻塞

image.png