pprof 性能分析工具

pprof 是什么

pprof 是 Go 内置的性能分析工具,用于定位 CPU 热点、内存分配、goroutine 阻塞、锁竞争等问题。它提供六类分析:

  • CPU:消耗 CPU 时间最多的函数;
  • 内存(heap):内存分配情况;
  • Goroutine:所有 goroutine 的堆栈;
  • 阻塞(block):同步原语导致的阻塞;
  • 互斥锁(mutex):锁竞争;
  • 线程创建(threadcreate):线程创建情况。

快速开始

只需导入 net/http/pprof 并在程序里起一个 HTTP 服务:

import _ "net/http/pprof"

go func() {
    log.Println(http.ListenAndServe("localhost:6060", nil))
}()

浏览器访问即可看到所有 profile 的入口:

http://localhost:6060/debug/pprof/          // 总览
http://localhost:6060/debug/pprof/heap      // 内存
http://localhost:6060/debug/pprof/profile?seconds=30  // CPU,采集30秒
http://localhost:6060/debug/pprof/goroutine?debug=2   // goroutine 堆栈

命令行分析

CPU 分析

# 采集 30 秒 CPU profile 并进入交互式分析
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

# 交互命令
top            # 最耗 CPU 的函数
list 函数名     # 函数内部逐行耗时
web            # 生成调用图(需安装 graphviz)

内存分析

go tool pprof http://localhost:6060/debug/pprof/heap

# 交互命令
top -cum   # 按累计分配排序
list       # 函数内部逐行分配
# 用 -http 直接在浏览器里看火焰图/调用图
go tool pprof -http=:8080 http://localhost:6060/debug/pprof/heap

Goroutine / 阻塞分析

go tool pprof http://localhost:6060/debug/pprof/goroutine   # 看 goroutine 最多的调用栈
go tool pprof http://localhost:6060/debug/pprof/block       # 看阻塞热点

代码内手动采集

// CPU
f, _ := os.Create("cpu.prof")
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()

// 内存快照
f, _ := os.Create("mem.prof")
pprof.WriteHeapProfile(f)
f.Close()

基准测试里的 pprof

func BenchmarkX(b *testing.B) {
    f, _ := os.Create("bench.prof")
    pprof.StartCPUProfile(f)
    defer pprof.StopCPUProfile()
    for i := 0; i < b.N; i++ {
        // 被测代码
    }
}

排查案例

内存泄漏

# 采集两个时间点的 heap,对比增长
go tool pprof -http=:8080 http://localhost:6060/debug/pprof/heap

重点看持续增长的分配来源,通常是全局缓存、未关闭的 goroutine 持有引用等。

CPU 热点

go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
# top 看热点函数,list 定位到具体行

注意事项

  • 默认 CPU 采样频率 100Hz;阻塞/互斥分析需要先设置采样率:runtime.SetBlockProfileRate(1)runtime.SetMutexProfileFraction(1)
  • heap profile 显示的是分配情况而非当前占用,区分”累积分配”和”存活”两个视图;
  • 生产环境开 pprof 端点要注意:只绑内网地址或加鉴权,否则任何人都能拉取 profile;
  • 采样时长一般 30–60 秒,程序繁忙时分析最有意义。
滚动至顶部