Go性能优化分析 | 青训营笔记

60 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天

一、重点内容

pprof是用于可视化地分析Go程序的工具。

二、知识点介绍

pprof功能简介

image.png

三、实践案例

1. 搭建pprof实践项目

github.com/wolfogre/go… 项目提前埋入了一些炸弹代码,产生可观测的性能问题。编译运行之后,会占用1CPU核心和超过1GB的内存。

2. 运行pprof

go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"

image.png

3. pprof命令

  • topN:查看占用资源最多的函数
  • list:根据指定的正则表达式查找代码行 image.png
  • web:调用关系可视化 image.png

4. 堆内存

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

image.png

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

5. goroutine协程

go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"

火焰图

image.png

6. mutex锁

go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"

image.png

image.png

7. block阻塞

go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"

image.png

image.png

四、pprof采样过程和原理

1. CPU

  • 采样对象:函数调用和它们占用的时间
  • 采样率:100次/秒,固定值
  • 采样时间:从手动启动到手动结束
  • 操作系统:每10ms向进程发送一次SIGPROF信号
  • 进程:每次接收到SIGPROF会记录调用堆栈
  • 写缓冲:每100ms读取已经记录的调用栈并写入输出流

2. Heap-堆内存

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

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

  • Goroutine:记录所有用户发起且在运行中的goroutine的runtime.main的调用栈信息
  • ThreadCreate:记录程序创建的所有系统线程的信息

4. Block-阻塞 & Mutex- 锁

  • 阻塞操作
    • 采样阻塞操作的次数和耗时
    • 采样率:阻塞耗时超过阈值才会被记录,1为每次阻塞均记录
  • 锁竞争
    • 采样争抢锁的次数和耗时
    • 采样率:只记录固定比例的锁操作,1为每次加锁均记录