不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • Langchain
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • Langchain
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • GO基础

  • 面向对象

  • 并发编程

  • 常用库

    • 01.fmt
    • 02.Time包
    • 03.encoding/json包
    • 04.Flag
    • 05.Log
    • 06.IO操作
    • 07.Strconv
    • 08.net/http
    • 09.Context
    • 10.反射
    • 11.zap日志包
    • 12.viper配置管理
    • 13.gRPC
    • 14.jwt-go
    • 15.go-wrk压测
    • 16.Makefile
    • 17.cobor
    • 18.logrus
    • 19.cron定时
    • 20.machinery
    • 21.regexp2
    • 22.lo
    • 23.泛型
    • 24.pprof
      • 01.pprof
        • 1、pprof作用
        • 2、使用 pprof
        • 3、排查 CPU 占用过高
        • 1、top
        • 2、list
        • 3、web
        • 4、排查内存占用过高
        • 1、top
        • 2、list
        • 3、web
        • 5、频繁内存回收
        • 1、top
        • 2、list
        • 6、协程泄露
        • 1、top
        • 2、list
        • 3、web
        • 7、排查锁的争用
        • 1、top
  • 数据库操作

  • Beego框架

  • Beego商城

  • GIN框架

  • GIN论坛

  • 微服务

  • 设计模式

  • Go
  • 常用库
xiaonaiqiang
2024-02-29
目录

24.pprof

  • 参考 1 (opens new window)
  • 参考 2 (opens new window)

# 01.pprof

# 1、pprof作用

  • pprof 是一个性能分析工具,它可以帮助开发人员识别和解决应用程序中的性能瓶颈
  • 它可以分析应用程序的CPU利用率、内存使用情况、线程堆栈等信息,并生成可视化报告
  • 获取测试项目
git clone https://gitee.com/xiaonqedu/go-pprof-practice.git
cd go-pprof-practice 
1
2

# 2、使用 pprof

  • 编译并运行项目
  • 打开页面:http://localhost:6060/debug/pprof/
go build
./go-pprof-practice
1
2
  • 页面上展示了可用的程序运行采样数据,分别有
类型 描述 备注
allocs 内存分配情况的采样信息 可以用浏览器打开,但可读性不高
blocks 阻塞操作情况的采样信息 可以用浏览器打开,但可读性不高
cmdline 显示程序启动命令及参数 可以用浏览器打开,这里会显示 ./go-pprof-practice
goroutine 当前所有协程的堆栈信息 可以用浏览器打开,但可读性不高
heap 堆上内存使用情况的采样信息 可以用浏览器打开,但可读性不高
mutex 锁争用情况的采样信息 可以用浏览器打开,但可读性不高
profile CPU 占用情况的采样信息 浏览器打开会下载文件
threadcreate 系统线程创建情况的采样信息 可以用浏览器打开,但可读性不高
trace 程序运行跟踪信息 浏览器打开会下载文件,本文不涉及,可另行参阅《深入浅出 Go trace》 (opens new window)

# 3、排查 CPU 占用过高

  • go tool pprof http://localhost:6060/debug/pprof/profile

# 1、top

  • top 命令查看CPU占用情况
    • 很明显是 github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Eat 占用cpu时间非常长
tom.xiao@MBC02GG0L8MD6V ~ %  go tool pprof http://localhost:6060/debug/pprof/profile
(pprof) top

			# 注:下面指的时间都是函数占用CPU的时间
      # flat: 特定函数内部花费的时间(不包括在其子函数中花费的时间)
      # Flat%: 该函数自身的执行时间占比(在整个程序执行时间中)
      # Sum%: 该函数及其所有子函数执行时间占总执行时间的百分比
      # Cum: 函数及其子函数中累积花费的总时间
      # Cum%: 该函数及其子函数的执行时间占比(在整个程序执行时间中)
      flat  flat%   sum%        cum   cum%
   11380ms 98.61% 98.61%    11520ms 99.83%  github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Eat
     140ms  1.21% 99.83%      140ms  1.21%  runtime.asyncPreempt
         0     0% 99.83%    11530ms 99.91%  github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Live
         0     0% 99.83%    11540ms   100%  main.main
         0     0% 99.83%    11540ms   100%  runtime.main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 2、list

  • list Eat,查看问题具体在代码的哪一个位置
    • 可以看到,那个一百亿次空循环占用了大量 CPU 时间,至此,问题定位成功
(pprof) list Eat
Total: 11.54s
ROUTINE ======================== github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Eat in /Users/tom.xiao/tmpDir/go-pprof-practice/animal/felidae/tiger/tiger.go
    11.38s     11.52s (flat, cum) 99.83% of Total
         .          .     21:func (t *Tiger) Eat() {
         .          .     22:	log.Println(t.Name(), "eat")
         .          .     23:	loop := 10000000000
    11.38s     11.52s     24:	for i := 0; i < loop; i++ {
         .          .     25:		// do nothing
         .          .     26:	}
         .          .     27:}
         .          .     28:
         .          .     29:func (t *Tiger) Drink() {
1
2
3
4
5
6
7
8
9
10
11
12
13

# 3、web

  • 图形化显示调用栈信息
    • 图中,tiger.(*Tiger).Eat 函数的框特别大,箭头特别粗,pprof 生怕你不知道这个函数的 CPU 占用很高
# 事先在机器上安装 `graphviz`
brew install graphviz
# 继续在上文的交互式终端里输入 web (实际行为是产生一个 .svg 文件如下图,自动使用浏览器打开)
web
1
2
3
4

# 4、排查内存占用过高

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

# 1、top

  • top 命令查看内存占用情况
    • 很明显是 github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Eat 占用cpu时间非常长
tom.xiao@MBC02GG0L8MD6V ~ % go tool pprof http://localhost:6060/debug/pprof/heap 
(pprof) top
			# 注:下面指的时间都是函数占用内存的情况
      # flat: 特定函数占用内存数量
      # Flat%: 该函数自身使用内存占比
      # Sum%: 该函数及其所有子函数使用内存的百分比
      # Cum: 函数及其子函数中内侧使用量
      # Cum%: 该函数及其子函数使用内存占比
Showing nodes accounting for 2.41GB, 100% of 2.41GB total
      flat  flat%   sum%        cum   cum%
    1.20GB 50.00% 50.00%     1.20GB 50.00%  github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Pee.func1
    1.20GB 50.00%   100%     1.20GB 50.00%  github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Steal
         0     0%   100%     1.20GB 50.00%  github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Live
         0     0%   100%     1.20GB 50.00%  main.main
         0     0%   100%     1.20GB 50.00%  runtime.main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 2、list

  • list Steal,查看问题具体在代码的哪一个位置
    • 这里有个循环会一直向 m.buffer 里追加长度为 1 MiB 的数组,直到总容量到达 1 GiB 为止,且一直不释放这些内存
(pprof) list Steal
Total: 2.41GB
ROUTINE ======================== github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Steal in /Users/tom.xiao/tmpDir/go-pprof-practice/animal/muridae/mouse/mouse.go
    1.20GB     1.20GB (flat, cum) 50.00% of Total
         .          .     56:func (m *Mouse) Steal() {
         .          .     57:	log.Println(m.Name(), "steal")
         .          .     58:	max := constant.Gi
         .          .     59:	for len(m.buffer)*constant.Mi < max {
    1.20GB     1.20GB     60:		m.buffer = append(m.buffer, [constant.Mi]byte{})
         .          .     61:	}
         .          .     62:}
1
2
3
4
5
6
7
8
9
10
11

# 3、web

  • 图形化显示调用栈信息
    • mouse.(*Mouse).Steal 使用了大量内存不释放

# 5、频繁内存回收

  • go tool pprof http://localhost:6060/debug/pprof/allocs

# 1、top

  • top 命令查看GC清理情况
tom.xiao@MBC02GG0L8MD6V ~ % go tool pprof http://localhost:6060/debug/pprof/allocs
(pprof) top
      # flat: 一个函数内部分配的内存大小
      # Flat%: 特定函数占用的百分比
      # Sum%: 特定函数及其调用函数中性能或内存分配的总百分比
      # Cum: 函数及其调用函数中的累积性能或内存分配
      # Cum%: 特定函数及其调用函数中性能或内存分配的总累积百分比
      flat  flat%   sum%        cum   cum%
   24.88GB 78.39% 78.39%    24.88GB 78.39%  github.com/wolfogre/go-pprof-practice/animal/canidae/dog.(*Dog).Run
    3.83GB 12.06% 90.46%     3.83GB 12.06%  github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Pee.func1
    3.01GB  9.50%   100%     3.02GB  9.50%  github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Steal
         0     0%   100%    24.88GB 78.40%  github.com/wolfogre/go-pprof-practice/animal/canidae/dog.(*Dog).Live
         0     0%   100%     3.02GB  9.50%  github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Live
         0     0%   100%    27.90GB 87.92%  main.main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 2、list

  • list Run,查看问题具体在代码的哪一个位置
    • (*Dog).Run 会进行无意义的内存申请,而这个函数又会被频繁调用,这才导致程序不停地进行 GC
(pprof) list Run
Total: 31.73GB
ROUTINE ======================== github.com/wolfogre/go-pprof-practice/animal/canidae/dog.(*Dog).Run in /Users/tom.xiao/tmpDir/go-pprof-practice/animal/canidae/dog/dog.go
   24.88GB    24.88GB (flat, cum) 78.39% of Total
         .          .     41:func (d *Dog) Run() {
         .          .     42:	log.Println(d.Name(), "run")
   24.88GB    24.88GB     43:	_ = make([]byte, 16*constant.Mi)
         .          .     44:}
         .          .     45:
         .          .     46:func (d *Dog) Howl() {
         .          .     47:	log.Println(d.Name(), "howl")
         .          .     48:}
1
2
3
4
5
6
7
8
9
10
11
12

# 6、协程泄露

  • go tool pprof http://localhost:6060/debug/pprof/goroutine

# 1、top

  • top 命令查看goroutine泄漏情况
tom.xiao@MBC02GG0L8MD6V ~ % go tool pprof http://localhost:6060/debug/pprof/goroutine

(pprof) top
      flat  flat%   sum%        cum   cum%
        58 96.67% 96.67%         58 96.67%  runtime.gopark
         1  1.67% 98.33%          1  1.67%  runtime.goroutineProfileWithLabels
         0     0% 98.33%         50 83.33%  github.com/wolfogre/go-pprof-practice/animal/canidae/wolf.(*Wolf).Drink.func1
         0     0% 98.33%          6 10.00%  github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Pee.func1
         0     0% 98.33%          1  1.67%  internal/poll.(*FD).Accept
         0     0% 98.33%          1  1.67%  internal/poll.(*pollDesc).wait
         0     0% 98.33%          1  1.67%  internal/poll.(*pollDesc).waitRead (inline)
         0     0% 98.33%          1  1.67%  internal/poll.runtime_pollWait
         0     0% 98.33%          1  1.67%  main.main

1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 2、list

  • Drink 在不停地创建没有实际作用的协程
    • Drink 函数每次会释放 10 个协程出去,每个协程会睡眠 30 秒再退出
    • 而 Drink 函数又会被反复调用,这才导致大量协程泄露
(pprof) list Drink
Total: 60
ROUTINE ======================== github.com/wolfogre/go-pprof-practice/animal/canidae/wolf.(*Wolf).Drink.func1 in /Users/tom.xiao/tmpDir/go-pprof-practice/animal/canidae/wolf/wolf.go
         0         50 (flat, cum) 83.33% of Total
         .          .     33:		go func() {
         .         50     34:			time.Sleep(30 * time.Second)
         .          .     35:		}()
         .          .     36:	}
         .          .     37:}
         .          .     38:
         .          .     39:func (w *Wolf) Shit() {
1
2
3
4
5
6
7
8
9
10
11

# 3、web

# 7、排查锁的争用

  • 在程序中,除了锁的争用会导致阻塞之外,很多逻辑都会导致阻塞
  • go tool pprof http://localhost:6060/debug/pprof/block

# 1、top

tom.xiao@MBC02GG0L8MD6V ~ % go tool pprof http://localhost:6060/debug/pprof/block

(pprof) top
      flat  flat%   sum%        cum   cum%
  1866.51s 49.61% 49.61%   1866.51s 49.61%  runtime.chanrecv1
  1866.14s 49.60% 99.20%   1866.14s 49.60%  sync.(*Mutex).Lock (inline)
       30s   0.8%   100%        30s   0.8%  runtime.selectgo
         0     0%   100%   1866.14s 49.60%  github.com/wolfogre/go-pprof-practice/animal/canidae/wolf.(*Wolf).Howl
         0     0%   100%   1866.14s 49.60%  github.com/wolfogre/go-pprof-practice/animal/canidae/wolf.(*Wolf).Live
         0     0%   100%   1866.51s 49.61%  github.com/wolfogre/go-pprof-practice/animal/felidae/cat.(*Cat).Live
         0     0%   100%   1866.51s 49.61%  github.com/wolfogre/go-pprof-practice/animal/felidae/cat.(*Cat).Pee
         0     0%   100%   3732.66s 99.20%  main.main
         0     0%   100%        30s   0.8%  net/http.(*ServeMux).ServeHTTP
         0     0%   100%        30s   0.8%  net/http.(*conn).serve
1
2
3
4
5
6
7
8
9
10
11
12
13
14
上次更新: 2024/3/18 16:59:48
23.泛型
01.GORM入门

← 23.泛型 01.GORM入门→

最近更新
01
300.整体设计
06-10
02
06.LangGraph
06-09
03
202.AI销售智能体
06-07
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式