这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天.
一.简介
1.性能调优原则
- 要依靠数据不是猜测
- 要定位最大瓶颈而不是细枝末节
- 不要过早优化(避免后期修改出问题)
- 不要过度优化
二.性能分析工具pprof
1.准备工作
1.运行pprof分析的程序
2.进入http://127.0.0.1:6060/debug/pprof/ ,可以查看信息,但信息比较多,看起来不是很清晰.(注意你所使用的端口号)
2.CPU
执行
go tool pprof "http://127.0.0.1:6060/debug/pprof/profile?seconds=10"(注意你所使用的端口号) ,等一会后可以看见类似下面的信息:
top
- 命令: topN
- 查看占用资源最多的函数
- flat: 当前函数本身的执行耗时
- flat%: flat占cpu总时间的比例
- sum%: 上面每一行的flat%总和
- cum: 指当前函数本身加上其调用函数的总耗时
- cum%: cum占cpu总时间的比例
- flat == Cum,函数中没有调用其他函数
- flat == 0 ,函数只有其他函数的调用
list
- 命令: list
- 根据指定的正则表达式查找代码行
可以查找出最消耗时间的那一行
web(需要安装Graphviz)
- 命令: web
- 调用关系可视化
3.Heap-堆内存
使用go tool pprof "http://localhost:6060/debug/pprof/heap" 同样的方法进入
top
使用可视化界面
使用
go tool pprof -http=:8080 http://localhost:6060/debug/pprof/heap
或者将http://localhost:6060/debug/pprof/heap下载下来以go tool pprof -http=:8080 [路径]的形式打开
top视图
点击左上角的view选择top
Source视图
点击左上角的view选择source
smaple
- alloc_objects: 程序累计申请的对象数
- alloc_space: 程序累计申请的内存大小
- inuse_objects: 程序当前持有的对象数
- inuse_space: 程序当前占同的内存大小
4. goroutine
使用
go tool pprof -http=:8080 http://localhost:6060/debug/pprof/goroutine
火焰图
点击左上角的view选择Flame Graph
- 由上到下表示调用顺序
- 每一块代表一个函数,越长代表占用CPU的时间更长
- 火焰图是动态的,支持点击块进行分析
找到问题函数后在source中查询函数名,查找问题原因
5.mutex-锁
使用
go tool pprof -http=:8080 http://localhost:6060/debug/pprof/mutex在source中查询问题函数.
6.block-阻塞
使用
go tool pprof -http=:8080 http://localhost:6060/debug/pprof/block查找问题函数,解决问题
-
如果没有查到所有的block,可能是被过滤条件丢弃掉了
-
如果想要看全部block,可以打开
http://localhost:6060/debug/pprof/点进block查看
三.pprof采样过程和原理
1.CUP
-
采用对象: 函数调用和它们占用的时间
-
采样率: 100次/秒,固定值
-
采样时间: 从手动启动到手动结束
-
操作系统
- 每10ms向进程发送一次SIGPROF信号
-
进程
- 每次接收到SIGPROF会记录调用栈堆
-
写缓冲
- 每100ms读取以及记录的调用栈并写入输出流
- 每100ms读取以及记录的调用栈并写入输出流
2.Heap-堆内存
- 采样程序通过内存分配器在堆上分配和释放的内存,记录分配/释放的大小和数量
- 采样率:每分配512KB记录一次,可在运行开头修改.1为每次分配均记录
- 采样时间:从程序运行开始到采样时
- 采样指标: alloc_space,alloc_objects.inuse_space,inuse_objects
- 计算方式:inuse = alloc - free
3.Goroutine-协程 && ThreadCreate-线程创建
- Goroutine
- 记录使用用户发起且在运行中的goroutine(即非出口runtime开头的) runtime.main的调用栈信息
- ThreadCreate
- 记录程序创建的所有系统线程的信息
- 记录程序创建的所有系统线程的信息
4.Block-阻塞 && Mutex_锁
-
阻塞
- 采样阻塞操作的次数和耗时
- 采样率:阻塞耗时超过阀值的才会被记录,1为每次阻塞均记录
-
锁竞争
- 采样争抢锁的次数和耗时
- 采样率:只记录固定比例的锁操作,1为每次加锁均操作