6.5 性能分析: pprof 工具的简单使用

http://image.iswbm.com/20200607145423.png

pprof 是 Go 程序性能分析常用的工具,关于 pprof 有很多的包,它们分别是:

  • runtime/pprof:Go 的内置库,比较基础,不常用

  • pkg/profile:对 runtime/pprof 进行简化,只需要一行代码即可,等程序运行结束后才能分析

  • net/http/pprof:最好用的库,可以暴露 http 服务实时获取分析

本文,我仅使用 pkg/profile 进行演示,后面有机会再来补充 net/http/pprof 的,关于这些包的详细使用,可以查看你不知道的 Go 之 pprof,写得非常详细

1. 准备工作

1.1 准备依赖

下载 pprof

go get github.com/pkg/profile

安装 graphviz ,后面可视化分析要用

# centos
yum install -y graphviz

# ubuntu
apt-get install graphviz

# mac
brew install graphviz

1.2 准备代码

先创建临时项目

go mod init iswbm.com/demo-pprof

然后准备两个文件:

  • pprof-cpu.go (待补充)

  • pprof-mem.go

    package main
    
    import (
      "github.com/pkg/profile"
            "math/rand"
    )
    
    const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
    func randomString(n int) string {
      b := make([]byte, n)
      for i := range b {
          b[i] = letterBytes[rand.Intn(len(letterBytes))]
      }
      return string(b)
    }
    
    func concat(n int) string {
      s := ""
      for i := 0; i < n; i++ {
          s += randomString(n)
      }
      return s
    }
    
    func main() {
            defer profile.Start(profile.MemProfile, profile.MemProfileRate(1)).Stop()
      concat(100)
    }
    

2. 开始分析

以分析内存为例,直接运行该 pprof-mem.go,会生成两个 mem.pprof 文件

$ go run pprof-cpu.go
2022/01/19 06:53:02 profile: memory profiling enabled (rate 1), /tmp/profile645664769/mem.pprof
2022/01/19 06:53:02 profile: memory profiling disabled, /tmp/profile645664769/mem.pprof

2.1 命令行界面分析

指定这两个文件运行分析

$ go tool pprof /tmp/profile645664769/mem.pprof

再敲入 top,就可以看到分析的结果,可以看到 98% 的内存都是由 main.concat 函数产生的。

http://image.iswbm.com/20220119150631.png

2.2 可视化界面分析

然后指定这两个文件运行分析

$ go tool pprof -http=0.0.0.0:9999 /tmp/profile645664769/mem.pprof
Serving web UI on http://0.0.0.0:9999
http://0.0.0.0:9999

在浏览器访问该地址

然后就可以看到像下面这样的可视化界面,一下子就可以看出 main.concat 的区域最大

http://image.iswbm.com/20220119150344.png