这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天
课程内容与选题缘由
回顾了一下之前性能调优的课程,打算巩固一下性能调优工具pprof的使用以后查阅
pprof简介
pprof是Go语言中用于可视化和性能分析的工具。它可以收集程序运行时的性能数据,并生成分析报告。通过这些报告,开发者可以找到程序中性能瓶颈,并采取措施优化程序性能。
pprof有很多用法,常用的有以下几种:
- 在程序中添加运行时间点,生成性能数据文件,再用pprof工具分析该文件
- 直接在程序运行时,通过http服务暴露出来pprof数据
- 通过运行pprof命令分析运行中的程序
pprof模块介绍
pprof视图类型—View
- 调用图Graph
- 火焰图FlameGraph
- 源码Source
- 反汇编Disassemble
调用图Graph
火焰图FlameGraph
- 每一块代表一个函数,越长占用CPU的时间越长
- 火焰图是动态的,支持点击块进行分析
源码Source
展示占据资源的函数代码细节
pprof采样类型—Sample
- CPU
- 堆内存—Heap
- 协程—Goroutine
- 锁—Mutex
- 阻塞—Block
- 线程创建—ThreadCreate
CPU
- flat:当前函数本身的执行耗时
- flat%:flat占CPU总时间的比例
- sum%:上面每一行的flat%总和
- cum:当前函数本身加上其调用函数的总耗时
- cum%:cum占CPU总时间的比例
堆内存
prrof分析页面中,堆内存的分析有4种sample:
- alloc_objects:程序累积申请的对象数
- inuse_objects:程序当前持有的对象数
- alloc_space:程序累计申请的内存大小
- inuse_space:程序当前占用的内存大小
通常我们只看inuse_space的数据,但是可能有一些函数的内存消耗没有被发现,因为存在内存被分配之后马上被GC掉的情况,依然会造成性能损失。
因此我们在分析堆内存的消耗数据是,要检查inuse_space和alloc_space的数据。
Goroutine
该火焰图中,由上到下表示协程的调用顺序
阻塞
go tool pprof <http://localhost:6060/debug/pprof/goroutine> 报告中的阻塞可能不会显示完全,是因为有节点被过滤了,所以得不到显示。
pprof的使用
导入"net/http/pprof"包
import _ "net/http/pprof"
pprof命令
top
在命令行中获取各函数的资源消耗数据
list
list+函数名
获取对应函数消耗资源的代码位置
web
⚠️ 必须先安装好Graphviz和dot环境获取性能分析的svg格式图片
go tool pprof 相关
命令行中输入 go tool pprof + 相关内容 的命令查看详细数据
- 示例命令
//在命令行中查看运行性能
go tool pprof "<http://localhost:6060/debug/pprof/profile?seconds=10>"
//在localhost:8080 排查CPU问题
go tool pprof -http=:8080 <http://localhost:6060/debug/pprof/profile>
//在localhost:8080 排查堆内存问题
go tool pprof -http=:8080 <http://localhost:6060/debug/pprof/heap>
//在localhost:8080 排查协程问题
go tool pprof -http=:8080 <http://localhost:6060/debug/pprof/goroutine>
//在localhost:8080 排查阻塞问题
go tool pprof -http=:8080 <http://localhost:6060/debug/pprof/block>
//在localhost:8080 排查锁问题
go tool pprof -http=:8080 <http://localhost:6060/debug/pprof/mutex>
Graphviz
用pprof的web 命令获取性能分析的时候
必须先下载Graphviz——一款开源的图形可视化软件,以及配置DOT环境,否则无法生成页面
- Grapphviz配置教程
【VS Code】Windows10下VS Code配置Graphviz和DOT语言环境_memcpy0的博客-CSDN博客
pprof采样过程与原理
CPU
- 采样对象:函数调用 和 他们占用的时间
- 采样率:100次/秒,固定值
- 采样时间:从 手动启动 到 手动结束
Heap
- 采样程序通过内存分配器在堆上分配和释放的内存,记录分配/释放的大小和数量
- 采样率:每分配512KB记录一次,可在运行开头修改,1为每次分配均记录
- 采样时间:从程序运行开始到采样时
- 采样指标:
alloc_space, alloc_objects, inuse_space, inuse_objects - 计算方式:
inuse = alloc - free
Goroutine-协程 & ThreadCreate线程创建
-
Goroutine
- 记录所有用户发起且在运行中的goroutine
- runtime.main 的调用栈信息
-
ThreadCreate
- 记录程序创建的所有系统线程的信息
Block-阻塞
- 采样阻塞操作的次数和耗时
- 采样率:阻塞耗时超过阈值得分才会比记录,1 为每次阻塞的均记录
Mutex-锁
- 采样争夺锁的次数和耗时
- 采样率:只记录固定比例的锁操作,1 为每次加锁的均记录