性能分析
先性能分析找到代码的问题,在进行性能优化
性能调优原则
- 要依靠数据不是猜测
- 要定位最大瓶颈而不是细枝末节
- 不要过早优化
- 不要过度优化
性能分析工具
浏览器查看:http://localhost:6060/debug/pprof/ 所有
CPU
1、终端查看:(方式1)
go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10" # seconds可选
2、命令:topN (N可以么有)
查看占用资源最多的函数
- flat:当前函数本身的执行耗时
- flat%:flat占CPU总时间的比例
- sum%:上面每一行的flat%总和
- cum:指当前函数本身加上其调用函数的总耗时
- cum%:cum占CPU总时间的L比例
Flat==Cum,函数中没有调用其他函数
Flat=O,函数中只有其他函数的调用
3、list Eat(具体函数)
根据指定的正则表达式查找具体代码行的消耗
4、命令:web 调用关系可视化图片
Heap-堆内存
1、更为全面的web图(可操作)查看(方式2)
go tool pprof -http=:8080 http://localhost:6060/debug/pprof/heap
2、直接图形化操作
- 查看top
- 查看sorce代码问题
3、其他东西
- alloc objects:程序累计申请的对象数
- inuse objects:程序当前持有的对象数
- alloc space:程序累计申请的内存大小
- inuse space:程序当前占用的内存大小
goroutine-协程
goroutine泄露也会导致内存泄露
1、更为全面的web图(可操作)查看(方式2)
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
由上到下表示调用顺序
每一块代表一个函数,越长代表占用CPU的时间更长
火焰图是动态的,支持点击块进行分析
2、看哪个火焰图Flame 大的就在source搜索定位
mutex-锁
1、更为全面的web图(可操作)查看(方式2)
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
block-阻塞
1、更为全面的web图(可操作)查看(方式2)
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
2、可能显示不全:
-
原因:终端查看 (方式1)
-
go tool pprof "http://localhost:6060/debug/pprof/block"
-
top
会丢弃cum一些太小的不统计,刚好过滤掉一下block的函数,其实只是合理的
-
-
解决:浏览器查看:http://localhost:6060/debug/pprof/ 所有
采样过程和原理(pprof)
CPU
采样对像:函数调用和它们占用的时间
采样率:100次/秒,固定值
采样时间:从手动启动到手动结束
开始采样 -> 设定信号处理函数 -> 开启定时器: 每隔10ms向系统要cpu的占用的时间记录到堆 停止采样 -> 取消信号处理函数 -> 关闭定时器: 每隔100ms将数据存档到缓存
Heap-堆内存
- 采样程序通过内存分配器在堆上分配和释放的内存,记录分配释放的大小和数量
- 采样率:每分配512KB记录一次,可在运行开头修改,1为每次分配均记录
- 采样时间:从程序运行开始到采样时
- 采样指标alloc space,alloc objects,inuse_space,.inuse_objects
- 计算当前内存方式:inuse = alloc(申请的内存)-free(空闲的内存)
Goroutine-协程&ThreadCreate-线程创建
Goroutine:
- 记录所有用户发起且在运行中的goroutine(即入口非runtime开头的) untime.main的调用栈信息
ThreadCreate:
- 记录程序创建的所有系统线程的信息
Block-阻塞&Mutex-锁
-
阻塞操作
采样阻塞操作的次数和耗时 采样率阻塞耗时超过阈值的才会被记录,1为每次阻塞均记录
-
锁竞争
采样争抢锁的次数和耗时
采样率只记录固定比例的锁操作,1为每次加锁均记录