day5 性能调优-pprof | 青训营笔记

82 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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" (注意你所使用的端口号) ,等一会后可以看见类似下面的信息: image.png

top

  • 命令: topN
  • 查看占用资源最多的函数
    image.png
  • flat: 当前函数本身的执行耗时
  • flat%: flat占cpu总时间的比例
  • sum%: 上面每一行的flat%总和
  • cum: 指当前函数本身加上其调用函数的总耗时
  • cum%: cum占cpu总时间的比例
  • flat == Cum,函数中没有调用其他函数
  • flat == 0 ,函数只有其他函数的调用

list

  • 命令: list
  • 根据指定的正则表达式查找代码行 image.png
    可以查找出最消耗时间的那一行

web(需要安装Graphviz)

  • 命令: web
  • 调用关系可视化 image.png

3.Heap-堆内存

使用go tool pprof "http://localhost:6060/debug/pprof/heap" 同样的方法进入 image.png

top

image.png

使用可视化界面

使用 go tool pprof -http=:8080 http://localhost:6060/debug/pprof/heap
或者将http://localhost:6060/debug/pprof/heap 下载下来以go tool pprof -http=:8080 [路径]的形式打开 image.png

top视图

点击左上角的view选择top image.png

Source视图

点击左上角的view选择source image.png

smaple

image.png

  • alloc_objects: 程序累计申请的对象数
  • alloc_space: 程序累计申请的内存大小
  • inuse_objects: 程序当前持有的对象数
  • inuse_space: 程序当前占同的内存大小

4. goroutine

使用 go tool pprof -http=:8080 http://localhost:6060/debug/pprof/goroutine image.png

火焰图

点击左上角的view选择Flame Graph image.png

  • 由上到下表示调用顺序
  • 每一块代表一个函数,越长代表占用CPU的时间更长
  • 火焰图是动态的,支持点击块进行分析

找到问题函数后在source中查询函数名,查找问题原因

5.mutex-锁

使用 go tool pprof -http=:8080 http://localhost:6060/debug/pprof/mutex image.png 在source中查询问题函数.

6.block-阻塞

使用go tool pprof -http=:8080 http://localhost:6060/debug/pprof/block image.png 查找问题函数,解决问题

  • 如果没有查到所有的block,可能是被过滤条件丢弃掉了
    image.png

  • 如果想要看全部block,可以打开http://localhost:6060/debug/pprof/点进block查看

三.pprof采样过程和原理

1.CUP

  • 采用对象: 函数调用和它们占用的时间

  • 采样率: 100次/秒,固定值

  • 采样时间: 从手动启动到手动结束 image.png

  • 操作系统

    • 每10ms向进程发送一次SIGPROF信号
  • 进程

    • 每次接收到SIGPROF会记录调用栈堆
  • 写缓冲

    • 每100ms读取以及记录的调用栈并写入输出流 image.png

2.Heap-堆内存

  • 采样程序通过内存分配器在堆上分配和释放的内存,记录分配/释放的大小和数量
  • 采样率:每分配512KB记录一次,可在运行开头修改.1为每次分配均记录
  • 采样时间:从程序运行开始到采样时
  • 采样指标: alloc_space,alloc_objects.inuse_space,inuse_objects
  • 计算方式:inuse = alloc - free

3.Goroutine-协程 && ThreadCreate-线程创建

  • Goroutine
    • 记录使用用户发起且在运行中的goroutine(即非出口runtime开头的) runtime.main的调用栈信息
  • ThreadCreate
    • 记录程序创建的所有系统线程的信息 image.png

4.Block-阻塞 && Mutex_锁

  • 阻塞

    • 采样阻塞操作的次数和耗时
    • 采样率:阻塞耗时超过阀值的才会被记录,1为每次阻塞均记录 image.png
  • 锁竞争

    • 采样争抢锁的次数和耗时
    • 采样率:只记录固定比例的锁操作,1为每次加锁均操作 image.png