Golang 常用的性能分析方法

1,152 阅读3分钟

「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战

Go 中常用的性能分析方法有 pprof, trace

pprof

cpu 分析

在计算机中 profiling 是指对应用程序的画像,指的是应用程序的 CPU 和内存使用情况。pprof 提供了一下功能。

  • CPU Profiling : CPU 分析, 按照一定的频率采集监听的应用程序使用情况, 可以确定应用程序在注定消耗 CPU 周期时花费时间的位置。
  • Memory Profiling : 内存分析,在应用程序员进行堆分配时记录堆栈跟踪, 用于监视当前和历史的内存使用情况
  • Blocking Profiling : 阻塞分析, 记录 Gorountine 阻塞等待同步的位置
  • Mutex Profiling : 互斥锁分析,报告互斥锁的竞争情况
package pprof

import (
	"fmt"
	"os"
	"runtime/pprof"
	"testing"
)

func Fib(n int) int {

	if n <= 1 {
		return 1
	}

	return Fib(n-1) + Fib(n-2)
}

func TestProf(t *testing.T) {
	f, _ := os.OpenFile("cpu.profile", os.O_CREATE|os.O_RDWR, 0644)
	_ = pprof.StartCPUProfile(f)
	defer func() {
		_ = f.Close()
	}()
	defer pprof.StopCPUProfile()

	n := 10
	for i := 0; i < 6; i++ {
		fmt.Printf("Fib(%d)=%d\n", n, Fib(n))
		n += 3 * i
	}

}

运行以上代码,会有 cpu.profile 文件生成 执行结果:

➜  pprof git:(master) ✗ go tool pprof cpu.profile
Type: cpu
Time: Feb 2, 2022 at 2:06pm (CST)
Duration: 703.35ms, Total samples = 510ms (72.51%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 510ms, 100% of 510ms total
      flat  flat%   sum%        cum   cum%
     460ms 90.20% 90.20%      500ms 98.04%  /GoProject/main/gobase/pprof.Fib
      40ms  7.84% 98.04%       40ms  7.84%  runtime.newstack
      10ms  1.96%   100%       10ms  1.96%  runtime.mallocgc
         0     0%   100%      510ms   100%  /GoProject/main/gobase/pprof.TestProf
         0     0%   100%       10ms  1.96%  runtime.convT64
         0     0%   100%      510ms   100%  testing.tRunner
(pprof) 

CPU 问题,具体可以参考: wangxiaoming.blog.csdn.net/article/det…

通过 输入 top 命令, 可以查看占据 CPU 最长的10个操作。

对参数做一些说明:

  • flat 本函数的执行耗时
  • flat% 本函数执行耗时占总耗时的百分比
  • sum% 函数占 CPU 时间累积占比,从小到大一致累积到 100%
  • cum 当前函数加上当前函数调用的函数占用 cpu 的总耗时
  • cum% 当前函数加上当前函数调用的函数 占 cpu 的总耗时比例

输入 web 之后会自动打开网页页面,能够看到网页页面看 CPU 的使用情况。 每个方块表示一个方法,被采用到的次数越多,方块就越大,图中 x of y ms 指本函数执行了CPU 使用了 x 毫秒, 本函数加上调用下游使用了 y ms

在这里插入图片描述

pprof 内存分析

具体分析可参考如下: wangxiaoming.blog.csdn.net/article/det…

火焰图

火焰图是一种直观的工具看出性能问题。

火焰图横坐标表示抽样数,抽到的次数越多,横坐标越宽。

火焰图的纵坐标表示的是调用栈, 每一层都是一个函数, 调用栈越深,火焰就越高,火焰的顶部就是正在执行的函数,每一层的上一层都死本层函数的父函数。

一般来说,火焰图顶部总宽度的比例越大,越容易出现性能问题。

在这里插入图片描述

trace

Go 语言中提供了机遇追踪的策略工具,一旦开启 trace, Go 中发生的所有特定事件会被记录下来,并支持将其保存在文件中以备后续出处理分析。

特定事件有:

  • 创建,启动和终止 gorountines
  • 阻塞/非阻塞 gorountines
  • 网络 IO
  • Syscalls
  • 垃圾回收

总结

pprof适合找到代码中最消耗 CPU 时间或者内存的代码块, trace 更适合理解 gorountine 是如何在各个 CPU 上运行的,可以看到什么时候运行,什么时候停止。