pprof 是一个强大的性能分析工具,可以捕捉到多维度的运行状态的数据,在程序运行过程中可以获取cpuheapblocktraces等执行信息

一般情况下使用下列三种pprof分析

  • runtime/pprof:采集程序(非 Server)的运行数据进行分析
  • net/http/pprof:采集 HTTP Server 的运行时数据进行分析
  • runtime/trace:采集Go程序运行中的所有的运行时事件

通常使用pprof做的事情

  • CPU 分析,按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况,可确定应用程序在主动消耗 CPU 周期时花费时间的位置
  • 内存分析,在应用程序进行堆分配时记录堆栈跟踪,用于监视当前和历史内存使用情况,以及检查内存泄漏
  • 阻塞分析,记录 goroutine 阻塞等待同步(包括定时器通道)的位置
  • 互斥锁分析,报告互斥锁的竞争情况

例子:

package mainimport ("iotcomm/app""log""net/http"_"net/http/pprof"
)func main()  {go func() {log.Println(http.ListenAndServe(":8080", nil))}()app.Run() //业务代码
}

通过浏览器查看pprof

通过打开浏览器http://localhost:8080/debug/pprof/我们可以得到

/debug/pprof/Types of profiles available:
Count   Profile
15  allocs
0   block
0   cmdline
23  goroutine
15  heap
0   mutex
0   profile
17  threadcreate
0   trace
full goroutine stack dump
Profile Descriptions:allocs: A sampling of all past memory allocations
block: Stack traces that led to blocking on synchronization primitives
cmdline: The command line invocation of the current program
goroutine: Stack traces of all current goroutines
heap: A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample.
mutex: Stack traces of holders of contended mutexes
profile: CPU profile. You can specify the duration in the seconds GET parameter. After you get the profile file, use the go tool pprof command to investigate the profile.
threadcreate: Stack traces that led to the creation of new OS threads
trace: A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace.

  • allocs :过去所有内存分配的采样
    heap profile: 4: 7584 [107: 422856] @ heap/1048576
    1: 5376 [1: 5376] @ 0xec672d 0xec66ea 0xec5813 0xec5f3e 0xec5deb 0xf23dba 0xf23d6b 0xef0bb7 0xf05c30 0xf24a71 0x8645a1
#    0xec672c    math/rand.NewSource+0x12c                                      C:/Users/DELL/go/pkg/mod/github.com/nats-io/nats.go@v1.11.1-0.20210623165838-4b75fc59ae30/nats.go:3505
#   0xec66e9    github.com/nats-io/nats%2ego.(*Conn).initNewResp+0xe9                          C:/Users/DELL/go/pkg/mod/github.com/nats-io/nats.go@v1.11.1-0.20210623165838-4b75fc59ae30/nats.go:3505
#   0xec5812    github.com/nats-io/nats%2ego.(*Conn).createNewRequestAndSend+0x492                 C:/Users/DELL/go/pkg/mod/github.com/nats-io/nats.go@v1.11.1-0.20210623165838-4b75fc59ae30/nats.go:3348
#   0xec5f3d    github.com/nats-io/nats%2ego.(*Conn).newRequest+0xdd                           C:/Users/DELL/go/pkg/mod/github.com/nats-io/nats.go@v1.11.1-0.20210623165838-4b75fc59ae30/nats.go:3430
#   0xec5dea    github.com/nats-io/nats%2ego.(*Conn).request+0x26a                         C:/Users/DELL/go/pkg/mod/github.com/nats-io/nats.go@v1.11.1-0.20210623165838-4b75fc59ae30/nats.go:3419
#   0xf23db9    github.com/nats-io/nats%2ego.(*Conn).Request+0x419                         C:/Users/DELL/go/pkg/mod/github.com/nats-io/nats.go@v1.11.1-0.20210623165838-4b75fc59ae30/nats.go:3398
#   0xf23d6a    iotcomm/app/system/admin/internal/service.(*varsSdk).JudgeIfNotifySDK+0x3ca                D:/IotComm/trunk/app/system/admin/internal/service/varsSdk.go:404
#   0xef0bb6    iotcomm/app/system/admin/internal/service.(*channelEntityVariableSubscribe).VariableChangedNotify+0xeb6    D:/IotComm/trunk/app/system/admin/internal/service/channelEntityVariableSubscribe.go:337
#   0xf05c2f    iotcomm/app/system/admin/internal/service.(*entityvarService).UpdateEntityVarValue+0x5af       D:/IotComm/trunk/app/system/admin/internal/service/entityVar.go:779
#   0xf24a70    iotcomm/app/system/admin/internal/service.NatsReport.func1.1+0x150                 D:/IotComm/trunk/app/system/admin/internal/service/varsSdk.go:52

由上可以看出,nats.go过去的一段时间内申请内存的操作最多

  • block:协程阻塞的情况,可以用来分析和查找死锁等性能瓶颈,默认不开启,可以调用runtime.SetBlockProfileRate开启来今行查看

列如:

func main()  {runtime.SetBlockProfileRate(1)go func() {log.Println(http.ListenAndServe(":8080", nil))}()app.Run()
}

可以得到以下block信息

--- contention:
cycles/second=3078668017
69212761621 34 @ 0x6fea9f 0xd50f7f 0x6f4641
#   0x6fea9e    sync.(*Cond).Wait+0x9e                 C:/Program Files/Go/src/sync/cond.go:56
#   0xd50f7e    github.com/nats-io/nats%2ego.(*Conn).waitForMsgs+0x4de C:/Users/DELL/go/pkg/mod/github.com/nats-io/nats.go@v1.11.1-0.20210623165838-4b75fc59ae30/nats.go:252538995547732 126 @ 0x6868ab 0x87cce5 0x6f4641
#   0x6868aa    runtime.chanrecv1+0x2a                 C:/Program Files/Go/src/runtime/chan.go:439
#   0x87cce4    github.com/gogf/gf/os/gtimer.(*Timer).loop.func1+0x84  C:/Users/DELL/go/pkg/mod/github.com/gogf/gf@v1.16.2/os/gtimer/gtimer_timer_loop.go:2138794859460 22 @ 0x6868eb 0xd51ff0 0x6f4641
#   0x6868ea    runtime.chanrecv2+0x2a                 C:/Program Files/Go/src/runtime/chan.go:444
#   0xd51fef    github.com/nats-io/nats%2ego.(*Conn).flusher+0xef  C:/Users/DELL/go/pkg/mod/github.com/nats-io/nats.go@v1.11.1-0.20210623165838-4b75fc59ae30/nats.go:2799
  • cmdline:主要是调用os.Args,获取程序启动时的命令及参数
  • goroutine:协程相关的报告信息
  • heap:堆以及一些垃圾回收的信息
heap profile: 6: 73120 [402: 2941872] @ heap/1048576
1: 32768 [2: 65536] @ 0x94b0a8 0x94c07e 0x94eafc 0x952c34 0x9536a5 0x960c9e 0x960db6 0xe2d7a5 0xe1b425 0xe08d68 0xe3c22a 0xe38a86 0xef002b 0xeeff33 0xf05c30 0xf24a71 0x8645a1
#   0x94b0a7    regexp.(*bitState).reset+0x227                                     C:/Program Files/Go/src/regexp/backtrack.go:91
#   0x94c07d    regexp.(*Regexp).backtrack+0x11d                                   C:/Program Files/Go/src/regexp/backtrack.go:319
#   0x94eafb    regexp.(*Regexp).doExecute+0x45b                                   C:/Program Files/Go/src/regexp/exec.go:535
#   0x952c33    regexp.(*Regexp).replaceAll+0x1b3                                  C:/Program Files/Go/src/regexp/regexp.go:617
#   0x9536a4    regexp.(*Regexp).ReplaceAllFunc+0xc4                                   C:/Program Files/Go/src/regexp/regexp.go:698
#   0x960c9d    github.com/gogf/gf/text/gregex.ReplaceFunc+0xbd                                C:/Users/DELL/go/pkg/mod/github.com/gogf/gf@v1.16.2/text/gregex/gregex.go:97
#   0x960db5    github.com/gogf/gf/text/gregex.ReplaceStringFunc+0xb5                          C:/Users/DELL/go/pkg/mod/github.com/gogf/gf@v1.16.2/text/gregex/gregex.go:121
#   0xe2d7a4    github.com/gogf/gf/database/gdb.FormatSqlWithArgs+0xc4                         C:/Users/DELL/go/pkg/mod/github.com/gogf/gf@v1.16.2/database/gdb/gdb_func.go:783
#   0xe1b424    github.com/gogf/gf/database/gdb.(*Core).DoQuery+0x2e4                          C:/Users/DELL/go/pkg/mod/github.com/gogf/gf@v1.16.2/database/gdb/gdb_core_underlying.go:49
#   0xe08d67    github.com/gogf/gf/database/gdb.(*Core).DoGetAll+0xe7                          C:/Users/DELL/go/pkg/mod/github.com/gogf/gf@v1.16.2/database/gdb/gdb_core.go:127
#   0xe3c229    github.com/gogf/gf/database/gdb.(*Model).doGetAllBySql+0x209                       C:/Users/DELL/go/pkg/mod/github.com/gogf/gf@v1.16.2/database/gdb/gdb_model_select.go:486
#   0xe38a85    github.com/gogf/gf/database/gdb.(*Model).doGetAll+0x165                            C:/Users/DELL/go/pkg/mod/github.com/gogf/gf@v1.16.2/database/gdb/gdb_model_select.go:55
#   0xef002a    github.com/gogf/gf/database/gdb.(*Model).All+0x32a                         C:/Users/DELL/go/pkg/mod/github.com/gogf/gf@v1.16.2/database/gdb/gdb_model_select.go:40
#   0xeeff32    iotcomm/app/system/admin/internal/service.(*channelEntityVariableSubscribe).VariableChangedNotify+0x232    D:/IotComm/trunk/app/system/admin/internal/service/channelEntityVariableSubscribe.go:330
#   0xf05c2f    iotcomm/app/system/admin/internal/service.(*entityvarService).UpdateEntityVarValue+0x5af       D:/IotComm/trunk/app/system/admin/internal/service/entityVar.go:779
#   0xf24a70    iotcomm/app/system/admin/internal/service.NatsReport.func1.1+0x150                 D:/IotComm/trunk/app/system/admin/internal/service/varsSdk.go:52# runtime.MemStats
# Alloc = 2465032
# TotalAlloc = 13052840
# Sys = 20343400
# Lookups = 0
# Mallocs = 193219
# Frees = 179358
# HeapAlloc = 2465032
# HeapSys = 11665408
# HeapIdle = 6758400
# HeapInuse = 4907008
# HeapReleased = 6471680
# HeapObjects = 13861
# Stack = 917504 / 917504
# MSpan = 165784 / 180224
# MCache = 14016 / 16384
# BuckHashSys = 1452585
# GCSys = 3215184
# OtherSys = 2896111
# NextGC = 4194304
# LastGC = 1630307387416162900
# PauseNs = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# PauseEnd = [1630307363484526700 1630307363640567200 1630307366356955300 1630307366377908700 1630307367513661900 1630307376617267500 1630307386409989000 1630307387416162900 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# NumGC = 8
# NumForcedGC = 0
# GCCPUFraction = 0.00015986017033100297
# DebugGC = false
  • mutex:锁互斥的使用情况,默认不开启, 需要调用需要在程序中调用runtime.SetMutexProfileFraction
    例如:
func main()  {runtime.SetMutexProfileFraction(1)go func() {log.Println(http.ListenAndServe(":8080", nil))}()app.Run()
}
  • threadcreate:线程的创建信息

通过终端查看pprof

  • 查看cpu在60s的使用情况
    go tool pprof http://localhost:8080/debug/pprof/profile?seconds=60
D:\IotComm\trunk>go tool pprof http://localhost:8080/debug/pprof/profile?seconds=60
Fetching profile over HTTP from http://localhost:8080/debug/pprof/profile?seconds=60
Saved profile in C:\Users\DELL\pprof\pprof.samples.cpu.003.pb.gz
Type: cpu
Time: Aug 30, 2021 at 3:20pm (CST)
Duration: 1mins, Total samples = 450ms ( 0.75%)
Entering interactive mode (type "help" for commands, "o" for options)

注:在使用浏览器查看pprof的网址,均可以使用go tool pprof + url的方式进入pprof命令行模式
例如go tool pprof http://localhost:8080/debug/pprof/block

(pprof) top
Showing nodes accounting for 837.48MB, 100% of 837.48MB totalflat  flat%   sum%        cum   cum%837.48MB   100%   100%   837.48MB   100%  main.main.func1

同样,使用top5,top10可以看到开销前5,前10占用率的函数
需要注意的是,通常情况下,占用率前5的一定是系统函数,如果发现自己写的函数占用率排在了前列,那就应该查一查时间,空间复杂度了


web可视化界面

func main()  {var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")var memprofile = flag.String("memprofile", "", "write memory profile to `file`")flag.Parse()if *cpuprofile != "" {f, err := os.Create(*cpuprofile)if err != nil {log.Fatal("could not create CPU profile: ", err)}if err := pprof.StartCPUProfile(f); err != nil {log.Fatal("could not start CPU profile: ", err)}defer pprof.StopCPUProfile()}if *memprofile != "" {f, err := os.Create(*memprofile)if err != nil {log.Fatal("could not create memory profile: ", err)}runtime.GC() // get up-to-date statisticsif err := pprof.WriteHeapProfile(f); err != nil {log.Fatal("could not write memory profile: ", err)}f.Close()}runtime.SetMutexProfileFraction(1)go func() {log.Println(http.ListenAndServe(":8080", nil))}()app.Run()
}

可以通过go run main.go --memprofile=mem.prof生成了mem.prof
可以通过go run main.go --cpuprofile=cpu.prof生成了cpu.prof

  • 启动pprof可视化界面
$ go tool pprof cpu.prof
$ (pprof) web


$ go tool pprof -http=:8080 cpu.prof

在这里必须安装graphviz,移步graphviz安装教程

使用test的功能及压测生成pprof文件移步到go test文档

pprof 性能分析相关推荐

  1. Go pprof 性能分析工具 - 详细使用图解

    一.Go导入pprof包的选择及go版本要求: 如果你是使用 net/http 包来构建web服务(有启动http服务),想查看服务运行的相关状态,就可以使用 net/http/pprof 包,导入方 ...

  2. go pprof 性能分析

    Go 的运行时性能分析接口都位于 runtime/pprof 包中.只需要调用 runtime/pprof 库即可得到我们想要的数据. CPU 性能分析 编写代码,生成分析报告 假设我们实现了这么一个 ...

  3. Golang pprof 性能分析与火焰图

    文章目录 1. 安装graphviz 1.1 下载 graphviz (windows 环境) 1.2 测试graphviz是否安装成功 2. 使用pprof 2.1 修改代码 2.2 火焰图生成 3 ...

  4. go pprof性能分析

    前提 Windows安装graphviz 下载地址: http://www.graphviz.org/download/ 添加环境变量:(默认)C:\Program Files\Graphviz 2. ...

  5. Go 学习笔记(81)— Go 性能分析工具 pprof

    Go 语言工具链中的 go pprof 可以帮助开发者快速分析及定位各种性能问题,如 CPU消耗 .内存分配及阻塞分析 .具体作用如下: 性能分析首先需要使用 runtime.pprof 包嵌入到待分 ...

  6. gbd 分析core文件_Go 性能分析工具 pprof 入门

    (给Go开发大全加星标) 来源:wudaijun https://wudaijun.com/2018/04/go-pprof/ [导读]pprof是golang用于性能分析的工具.可以生成图形和文本报 ...

  7. Go性能分析工具pprof详解

    文章目录 一.什么是pprof 二.怎么使用pprof 1. 工具型应用 2. 服务型应用 三.`pprof`数据分析 CPU Profiling top指令排序展示 web指令生成图示 list指令 ...

  8. golang性能分析工具pprof介绍

    1 golang性能分析工具pprof介绍 文章目录 1 golang性能分析工具pprof介绍 1.1 pprof简介 1.2 pprof引入方法 1.3 使用pprof进行分析的方法 1.3.1 ...

  9. go性能分析工具pprof

    pprof的用途 CPU Profiling:CPU 分析,按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况,可确定应用程序在主动消耗CPU 周期时花费时间的位置 Memory Pro ...

最新文章

  1. 如何安装系统认证签名过的APK
  2. SpringBoot使用JdbcTemplate案例(学习笔记)
  3. 七牛云存储Python SDK使用教程 - 上传策略详解
  4. oracle中变量前加冒号_ORACLE 变量的定义和使用
  5. 一个static和面试官扯了一个小时,舌战加强版
  6. Android 系统(112)---Android系统读取 CPU温度(MTK平台)
  7. linux 网卡无效 设置_请教,关于更改linux网卡配置文件后重启IP不生效的问题~
  8. 问题 K: n个数的最大值和最小值
  9. 网络安全之渗透实战学习
  10. 数字电路基础知识——时序逻辑电路之时序逻辑分析方法
  11. 使用uniapp实现全局悬浮按钮(可拖动)
  12. Tracup|使用项目管理独一无二的六大好处
  13. Spline样条曲线
  14. 为何晶振并联一个1MΩ电阻?晶振低温不起振如何解决?
  15. 35年夜linux版本竞技
  16. javascript设计模式-命令模式(command pattern)
  17. 我的世界潜影盒计算机存储器,我的世界:很多人以为自己了解潜影盒,其实他们只看到了表面!...
  18. 004-JDK的下载和安装
  19. 使用StreamReader逐行读取文件
  20. Arduino + SI5351 方波发生器

热门文章

  1. 努比亚牵手天威诚信,共同打造多域名网站安全解决方案
  2. 流媒体协议RTSP,HTTP,HTTPS, SDP
  3. JVM垃圾回收机制GC理解
  4. Docker国内镜像源介绍与更换
  5. 优麒麟 20.04-V3 发布,修复众多问题
  6. 阿里云排名第三,2019年云综合收入355.25亿元
  7. 【GIT】GitHub中的readme.md说明文档中如何将表格居中显示?
  8. HTML+JavaScript案例
  9. python进行接口压力测试(1秒1000个请求)
  10. [经验教程]一个爱奇艺VIP会员帐号怎么共享给多个朋友家人使用同一个爱奇艺会员账号?