脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - go pprof 的使用操作代码

go pprof 的使用操作代码

2022-11-23 10:18Grassto Golang

pprof 是 go 中进行性能分析的工具,可以提供可视化数据查看,这篇文章主要介绍了go pprof 的使用操作,需要的朋友可以参考下

背景

最近合作开发一个项目,项目部署发现了才跑了没多久,就直接宕机了,查看服务器信息发现在某个时间端内存猛的暴涨了非常多,由于是合作开发的项目,我仔细的检查了自己的拿块代码,都没啥问题,另一个开发也说自己的代码没啥问题。

这没理没据的争论也不是个事,突然想起还有 pprof 这么个东西,正好能用上了。一顿操作下来,总算是找到了问题的根源。

 

pprof 是什么

pprof 是 go 中进行性能分析的工具,可以提供可视化数据查看。

pprof 的采样方式

  • runtime/pprof
  • net/http/pprof
  • test

这里举例采样内存信息。

package main
import (
	"os"
	"runtime/pprof"
)

func main() {
	var buf = make([][1024 * 1024]byte, 0)
	for i := 0; i < 100; i++ {
		buf = append(buf, [1024 * 1024]byte{})
	}
	f, err := os.OpenFile("heapProfile", os.O_CREATE|os.O_TRUNC|os.O_RDWR, os.ModePerm)
	if err != nil {
		return 
	}
	err = pprof.WriteHeapProfile(f)
	if err != nil {
		return 
	}
	println("结束")
}

程序跑完之后会在本地生成 heapProfile 文件,命令行执行 go tool pprof heapProfile 可进入终端交互,可以输入 top 等命令查看:

go pprof 的使用操作代码

这里可以输入 web 查看可视化界面,如果遇到 Could not execute dot; may need to install graphviz. 错误,需要自行安装,网上教程很多,本篇不提了。

go pprof 的使用操作代码

顺带提一下 runtime.MemStats 结构体字段解释

Alloc uint64 //golang语言框架堆空间分配的字节数
TotalAlloc uint64 //从服务开始运行至今分配器为分配的堆空间总 和,只有增加,释放的时候不减少
Sys uint64 //服务现在系统使用的内存
Lookups uint64 //被runtime监视的指针数
Mallocs uint64 //服务分配内存对象的次数
Frees uint64 //服务回收内存对象的次数
HeapAlloc uint64 //服务分配的堆内存字节数
HeapSys uint64 //系统分配的作为运行栈的内存
HeapIdle uint64 //申请但是未分配的堆内存或者回收了的堆内存(空闲)字节数
HeapInuse uint64 //正在使用的堆内存字节数
HeapReleased uint64 //返回给OS的堆内存,类似C/C++中的free。
HeapObjects uint64 //堆内存块申请的量
StackInuse uint64 //正在使用的栈字节数
StackSys uint64 //系统分配的作为运行栈的内存
MSpanInuse uint64 //用于测试用的结构体使用的字节数
MSpanSys uint64 //系统为测试用的结构体分配的字节数
MCacheInuse uint64 //mcache结构体申请的字节数(不会被视为垃圾回收)
MCacheSys uint64 //操作系统申请的堆空间用于mcache的字节数
BuckHashSys uint64 //用于剖析桶散列表的堆空间
GCSys uint64 //垃圾回收标记元信息使用的内存
OtherSys uint64 //golang系统架构占用的额外空间
NextGC uint64 //垃圾回收器检视的内存大小
LastGC uint64 // 垃圾回收器最后一次执行时间。
PauseTotalNs uint64 // 垃圾回收或者其他信息收集导致服务暂停的次数。
PauseNs [256]uint64 //一个循环队列,记录最近垃圾回收系统中断的时间
PauseEnd [256]uint64 //一个循环队列,记录最近垃圾回收系统中断的时间开始点。
NumForcedGC uint32 //服务调用runtime.GC()强制使用垃圾回收的次数。
GCCPUFraction float64 //垃圾回收占用服务CPU工作的时间总和。如果有100个goroutine,垃圾回收的时间为1S,那么就占用了100S。
BySize //内存分配器使用情况

net/http/pprof

需要引入 net/http/pprof 包

package main
import (
	"net/http"
	_ "net/http/pprof"
)

func main() {
	_ = http.ListenAndServe("0.0.0.0:6060", nil)
}

然后访问服务地址 http://127.0.0.1:6060/debug/pprof 即可看到如下图所示的调试界面:

go pprof 的使用操作代码

  • allocs:查看过去所有内存分配的样本。
  • block:查看导致阻塞同步的堆栈跟踪。
  • cmdline: 当前程序的命令行的完整调用路径。
  • goroutine:查看当前所有运行的 goroutines 堆栈跟踪。
  • heap:查看活动对象的内存分配情况。
  • mutex:查看导致互斥锁的竞争持有者的堆栈跟踪。
  • profile: 默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件。
  • threadcreate:查看创建新 OS 线程的堆栈跟踪。
  • trace:略,trace可以单独写一篇文章来介绍。

这里需要注意,如果需要对 block 和 mutex 的信息进行追踪,需要在代码中显式加上以下代码:

	runtime.SetBlockProfileRate(1) // 开启对阻塞操作的跟踪,block  
	runtime.SetMutexProfileFraction(1) // 开启对锁调用的跟踪,mutex

 

gin 框架使用 pprof

gin 是 go 社区中使用较为广泛的一个 http 服务框架,其使用 pprof 进行性能分析,也有现成的轮子可以使用,引入 github.com/gin-contrib/pprof 即可,其实就是对于 net/http/pprof 的一个包装。

package main
import (
	"github.com/gin-contrib/pprof"
	"github.com/gin-gonic/gin"
)

func main() {
	engine := gin.Default()
	pprof.Register(engine)
}

test

 	-bench=.
       进行性能测试,“.”是正则匹配,匹配了所有的测试函数

  -benchmem
      打印出申请内存的次数。一般用于简单的性能测试,不会导出数据文件。

  -blockprofile block.out
      将协程的阻塞数据写入特定的文件(block.out)。如果-c,则写成二进制文件。

  -cpuprofile cpu.out
      将协程的CPU使用数据写入特定的文件(cpu.out)。如果-c,则写成二进制文件。

  -memprofile mem.out
      将协程的内存申请数据写入特定的文件(mem.out)。如果-c,则写成二进制文件。

  -mutexprofile mutex.out
      将协程的互斥数据写入特定的文件(mutex.out)。如果-c,则写成二进制文件。

  -trace trace.out
      将执行调用链写入特定文件(trace.out)。

test 导出的数据也需要通过 go tool pprof 来分析。

 

火焰图

安装

go get -u github.com/google/pprof

启动

pprof -http=:8080 heapProfile

访问 http://localhost:8080 可以得到下图:

go pprof 的使用操作代码

每个块都是可点击的,可以进行深度分析。

 

总结

pprof 是 go 中做性能分析的很强大的一个工具,支持内存,cpu,锁,goroutine 等数据采集,本篇主要是做个简单介绍,真正进行分析的时候,需要耐心了解各种图,数据展示的含义,一般来说还是比较好理解的。

pprof 性能分析是个很大的知识点,本篇仅做了简单的介绍,最好自己深入理解学习一下。

参考

golang pprof 实战-CPU,heap,alloc,goroutine,mutex,block

Go 语言编程之旅-pprof篇

实用go pprof使用指南

到此这篇关于go pprof 的使用的文章就介绍到这了,更多相关go pprof 使用内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/DisMisPres/article/details/127008874

延伸 · 阅读

精彩推荐
  • GolangGo语言中io包核心接口示例详解

    Go语言中io包核心接口示例详解

    Go的io包提供了io.Reader和io.Writer接口,分别用于数据的输入和输出,下面这篇文章主要给大家介绍了关于Go语言中io包核心接口的相关资料,需要的朋友可以参考...

    漫漫Coding路7862022-01-24
  • Golanggo grpc安装使用教程

    go grpc安装使用教程

    gRPC是由Google主导开发的RPC框架,使用HTTP/2协议并用ProtoBuf作为序列化工具。这篇文章主要介绍了go grpc安装使用教程,需要的朋友可以参考下 ...

    hncscwc5732020-05-14
  • GolangGo如何实现json字符串与各类struct相互转换

    Go如何实现json字符串与各类struct相互转换

    这篇文章主要介绍了Go如何实现json字符串与各类struct相互转换,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...

    FeelTouch Labs10562022-08-30
  • Golanggolang 随机数的两种方式

    golang 随机数的两种方式

    本文主要介绍了golang 随机数的两种方式,一种是伪随机,另一种是真随机,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习...

    @航空母舰6842022-07-05
  • GolangGo 语言入门学习之时间包

    Go 语言入门学习之时间包

    这篇文章主要介绍了Go 语言入门学习之时间包,GO 语言提供了 ​​time​​包来测量和显示时间,下文关于GO时间包的相关介绍需要的小伙伴可以参考一下...

    宇宙之一粟7222022-09-28
  • Golang安装了多个版本的 Go,该怎么用才正确?

    安装了多个版本的 Go,该怎么用才正确?

    实际开发中会接触到不同的开源项目,而这些项目有可能是不同团队开发的,使用的 go 版本都是不一样的。...

    Go编程时光10022021-07-29
  • Golang嗯,你觉得 Go 在什么时候会抢占 P?

    嗯,你觉得 Go 在什么时候会抢占 P?

    有新的小伙伴会产生更多的疑问,那就是在 Go 语言中,是如何抢占 P 的呢,这里面是怎么做的?今天这篇文章我们就来解密抢占 P。 ...

    脑子进煎鱼了8202021-04-20
  • GolangGoFrame的gmap相比Go原生的map,天然支持排序和有序遍历!?

    GoFrame的gmap相比Go原生的map,天然支持排序和有序遍历!?

    GoFrame提供的gmap字典类型,包含多个数据结构的map容器:HashMap、TreeMap和ListMap。其中TreeMap支持排序,TreeMap和ListMap支持有序遍历。...

    程序员升级打怪之旅6842022-11-03