go通过pprof定位groutine泄漏

news2024/10/5 18:34:46

日常开发中除了会出现Panic、ErrorInfo等通过日志很容易捕捉到的错误,还会出现内存泄漏、CPU激增等日志难以捕捉的问题。今天小老虎就给大家介绍下如何使用pprof去捕捉内存、CPU这些日志难以排查到的问题。

pprof的访问

pprof是Golang的性能分析工具,可以帮助我们查看程序在运行过程中CPU、内存、协程、锁的详细信息,对于定位程序中的bug非常有帮助。在Golang内存泄漏的七种场景中小老虎对内存泄漏可能出现的场景做了详细的介绍,下面以死锁造成的内存泄漏为例,来看看怎样使用pprof定位到内存泄漏的位置。

Golang已经帮助我们封装好了一个pprof服务,我们这需要在代码中开启这个服务,并访问对于的url就可以轻松获取到程序运行时的资源情况。

//启动pprof服务供外部访问func pprofServer() {    ip := "0.0.0.0:6060"    if err := http.ListenAndServe(ip, nil); err != nil {        fmt.Printf("start pprof failed on %s\n", ip)    }}
//协程拿到锁未释放,其他协程获取锁会阻塞,模拟内存泄漏func mutexTest() {    mutex := sync.Mutex{}    for i := 0; i < 10; i++ {        go func() {            mutex.Lock()            fmt.Printf("%d goroutine get mutex", i)            //模拟项目中后续代码耗时            time.Sleep(100 * time.Millisecond)        }()    }    time.Sleep(10 * time.Second)}
func main() {    go pprofServer()    mutexTest()}

在浏览器中输入地址http://127.0.0.1:6060/debug/pprof/

Image

比较常用的有下面五种信息

goroutine:所有goroutine的详细信息,包括协程数量,协程调用栈

heap:程序堆内存信息(每1000次内存申请采样一次)

mutex:锁的调用信息

trace:程序调用栈信息

profile:程序执行的CPU信息(每1秒采样100次)

点击查看goroutine信息

Image

image-20220306141533652

可以看到程序一共有15个协程其中有9个协程阻塞在了获取锁的位置,将url中的debug=1改为debug=2查看每个goroutine的详细信息。

debug=2查看每个goroutine的详细信息。

Image

可以看到协程号为21和22的协程都阻塞在了锁的获取上,阻塞时间为5min。下面再通过代码很容易就定位到了goroutine泄漏的原因是获取锁失败了。

命令行交互

实际开发中,有些程序是部署在内网服务器中的,这时没有浏览器来提供可视化的界面,就需要通过命令来查看资源的使用情况。使用命令go tool pprof url可以获取指定的profile文件,该命令会发起http请求,然后获取到资源信息存储到本地,之后就可以使用命令查看运行信息,以下是5类请求的方式:​​​​​​​

# 下载cpu profile,默认从当前开始收集30s的cpu使用情况,需要等待30sgo tool pprof http://localhost:6060/debug/pprof/profile   go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60     # wait60s # 下载heap profilego tool pprof http://localhost:6060/debug/pprof/heap      
# 下载goroutine profilego tool pprof http://localhost:6060/debug/pprof/goroutine 
# 下载block profilego tool pprof http://localhost:6060/debug/pprof/block    
# 下载mutex profilego tool pprof http://localhost:6060/debug/pprof/mutex

等待收集完成后就可以通过命令查看相应的信息,所有的交互命令都可以通过help指令查看。​​​​​​​

go tool pprof http://localhost:6060/debug/pprof/profileFetching profile over HTTP from http://localhost:6060/debug/pprof/profileSaved profile in /pprof/pprof.samples.cpu.016.pb.gzType: cpuTime: Mar 6, 2022 at 4:15pm (CST)Duration: 30s, Total samples = 290ms ( 0.97%)Entering interactive mode (type "help" for commands, "o" for options)(pprof) help  Commands:    callgrind        Outputs a graph in callgrind format    comments         Output all profile comments    disasm           Output assembly listings annotated with samples    dot              Outputs a graph in DOT format    eog              Visualize graph through eog    evince           Visualize graph through evince    gif              Outputs a graph image in GIF format    gv               Visualize graph through gv    kcachegrind      Visualize report in KCachegrind    list             Output annotated source for functions matching regexp

常用的命令有三种top、list、traces

top N:可以获取程序中资源消耗最大的前N个函数,例如输入top 10可以查看CPU消耗前十的函数​​​​​​​

(pprof) top 10Showing nodes accounting for 270ms, 93.10% of 290ms totalShowing top 10 nodes out of 19      flat  flat%   sum%        cum   cum%      90ms 31.03% 31.03%      130ms 44.83%  runtime.kevent      40ms 13.79% 44.83%       40ms 13.79%  runtime.libcCall      30ms 10.34% 55.17%       30ms 10.34%  runtime.kevent_trampoline      20ms  6.90% 62.07%       50ms 17.24%  runtime.checkTimers      20ms  6.90% 68.97%      250ms 86.21%  runtime.findrunnable      20ms  6.90% 75.86%       20ms  6.90%  runtime.lock2      20ms  6.90% 82.76%       30ms 10.34%  runtime.runtimer      10ms  3.45% 86.21%       10ms  3.45%  runtime.(*randomEnum).next (inline)      10ms  3.45% 89.66%       10ms  3.45%  runtime.runOneTimer      10ms  3.45% 93.10%       10ms  3.45%  runtime.runqget

top指令会统计下面五种信息

  • flat: 函数本身占用的CPU时间。

  • flat%: 本函数CPU占使用中CPU总量的百分比。

  • sum%: 前面每一行flat百分比的累加,比如第2行的44.3%=第1行的31.03%+当前函数的13.79%

  • cum: 是累计量,例如main函数调用子函数mutexTest,那么子函数mutexTest的CPU使用量也会被记进来

  • cum%: 是累计量占总量的百分比

list func:产看某个函数的资源使用信息,函数匹配使用的是正则匹配。​​​​​​​

(pprof) list mutexTestTotal: 7.73sROUTINE ======================== main.mutexTest.func1 in article/go/pprof/main.go         0      3.82s (flat, cum) 49.42% of Total         .          .     19:                   fmt.Printf("%d goroutine get mutex", i)         .          .     20:                   //模拟实际开发中的操作耗时         .          .     21:                   tick := time.Tick(time.Second / 100)         .          .     22:                   var buf []byte         .          .     23:                   for range tick {         .      3.82s     24:                           buf = append(buf, make([]byte, 1024*1024)...)         .          .     25:                   }         .          .     26:                   time.Sleep(100 * time.Millisecond)         .          .     27:                   wg.Done()         .          .     28:           }()         .          .     29:   }

显示该函数的占用0s(小数点后俩位则被舍去),累计上子函数的调用占用3.82s,占总CPU使用时间的49.42%。耗时主要积累在第24行,占用了3.82s。

在实际项目中可能会出现不同包中函数名相同的情况,尤其是接口中函数的问题定位,如果使用模糊查找自己想看的函数会很麻烦,这里提供几种特殊的正则匹配方式。(假设包括work的多个包中都有Show方法 ,以work包的特殊处理为例)

  • 模糊匹配:输入函数的名称

  • 精确匹配 :artical/go/pprof/main.Test,从根路径查找到包,使用包.方法名精确表示

  • 结构体指针方法:list Show -focus = work* 只展示work包中的Show方法(等号俩边要有空格)

  • 忽略某些包:list Show -work* 不展示work包中的Show方法

traces:查看函数调用栈信息

可视化工具

上面介绍的俩种方法都是pprof自带的检测方法,虽让能够帮助定位到程序的问题所在,但是每次打开CPU和内存分析文件都是密密麻麻的数字和代码,还是蛮头疼的,下面介绍pprof结合graphviz带来的可视化服务,是问题定位能够更加清晰。(首先需要下载graphviz)

首先将信息倒入到文件中curl -sK -v http://localhost:6060/debug/pprof/profile > cpu.out

然后用 go tool 工具go tool pprof -http=:8080 heap.out 使用该命令导出文件起一个服务,会自动跳到 UI 界面

Image

节点中的数字表示flat(函数使用量) of cum(函数包括子函数的使用量) cum%(cum占总使用量的百分比),节点越大越红表示该接节点的flat值越大,线越粗表示指向的节点cum值越大。

VIEW

Image

image-20220306173905386

Top:和top命令相同,将函数按资源使用进行排名

Graph:如图的函数调用逻辑图以及节点使用

Flame Graph:火焰图,资源使用按从大到小排列,点击可看详细信息

Peek:打印每个调用栈的信息

Source:显示具体函数的资源消耗信息,类似list命令

Disassemble:显示样本总量

SAMPLE

Image

img

如果是内存信息SAMOLE这一栏有四个选项

alloc_objects:已分配的对象总量(不管是否已释放)

alloc_space:已分配的内存总量(不管是否已释放)

inuse_objects:已分配但尚未释放的对象数量

inuse_sapce:已分配但尚未释放的内存数量

REFINE

Image

搭配搜索框使用按正则表达式对内容进行过滤(list命令)

总结

本文介绍了pprof自带的浏览器访问方式,以及在服务器上通过命令获取资源信息的方式和三种常用命令,top可以获取程序中子源消耗的函数排名,list可以获取指定函数的详细信息,trance可以打印出函数的调用栈。最后介绍了ppro结合graphviz带来的可视化服务,可以使得操作更加便利,火焰图更是直观简洁,能够帮助我们快速定位问题所在

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/992300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Inno Setup 打包的文件以管理员权限运行

在 Inno Setup 安装目录中找到文件 SetupLdr.e32&#xff0c;用软件 ResourceHacker 打开。如下图&#xff0c;点开清单&#xff0c;找到 <requestedExecutionLevel level"asInvoker" uiAccess"false"/></requestedPrivileges>改为 <requ…

Nomad系列-Nomad网络模式

系列文章 Nomad 系列文章 概述 Nomad 的网络和 Docker 的也有很大不同, 和 K8s 的有很大不同. 另外, Nomad 不同版本(Nomad 1.3 版本前后)或是否集成 Consul 及 CNI 等不同组件也会导致网络模式各不相同. 本文详细梳理一下 Nomad 的主要几种网络模式 在Nomad 1.3发布之前&a…

CSS_文字渐变

/* 定义渐变背景样式 */ .gradient-text {background-image: linear-gradient(to right, #ff0000, #00ff00); /* 渐变色范围 */background-clip: text; /* 应用渐变背景到文本 */-webkit-background-clip: text; /* Safari 和 Chrome 的前缀 */color: transparent; /* 将文本颜…

ADS1115 模拟IIC

ADS1115是16位ADC&#xff0c;基准源内部可选&#xff0c;PGA 可提供从 256mV 到 6.144V 的输入范围。 地址可由ADDR引脚决定&#xff0c;一般接地&#xff0c;地址为0x90 写寄存器地址为0x90&#xff0c;读寄存器地址为0x91 ADS1115有4个控制寄存器&#xff0c;0x00,0x01,0x0…

debian apt安装mysqlodbc

mysql的deb包下载地址 下载后上传到linux后&#xff0c; #安装deb包 apt install ./mysql-apt-config_0.8.26-1_all.deb #更新源 apt-get update #搜索包 apt search odbc #安装包 apt-get install mysql-connector-odbc

3. 自定义datasource

一、自定义DataSource ​ 自定义DataSource有两大类&#xff1a;单线程的DataSource和多线程的DataSource 单线程&#xff1a;继承 SourceFunction 多线程&#xff1a;继承 ParallelSourceFunction&#xff0c;继承 RichParallelSourceFunction&#xff08;可以有其他的很多操…

origin中optimal cluster安装报错解决

1.在安装之后程序运行出错&#xff0c;报错信息为缺少numpy包。解决办法&#xff1a;打开窗口-脚本窗口&#xff0c;用pip安装numpy&#xff0c;其他缺少的包可用同样方法解决。 2.有的包在外部python中才有&#xff0c;通过origin无法下载。解决办法&#xff1a;在连接-python…

WIFI版本云音响设置教程阿里云平台版本

文章目录 WIFI本云音响设置教程介绍一、申请设备三元素1.登录阿里云物联网平台2.创建产品3.设置产品参数4.添加设备5.获取三元素 二、设置设备三元素1.打开MQTTConfigTools2.计算MQTT参数3.使用windows电脑的WIFI连接到设备热点4.设置参数5.配置设备连接路由器 三、阿里云物联网…

有始有终!

作者 | 磊哥 来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09; 转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09; 开始是立秋之日&#xff08;8.8 号&#xff09;&#xff0c;结束是白露之时&#xff08;9.8 号&#xff09;。 为期一月&…

Day60|leetcode 84.柱状图中最大的矩形

leetcode 84.柱状图中最大的矩形 题目链接&#xff1a;84. 柱状图中最大的矩形 - 力扣&#xff08;LeetCode&#xff09; 视频链接&#xff1a;单调栈&#xff0c;又一次经典来袭&#xff01; LeetCode&#xff1a;84.柱状图中最大的矩形_哔哩哔哩_bilibili 题目概述 给定 n 个…

CSS3技巧36:backdrop-filter 背景滤镜

CSS3 有 filter 滤镜属性&#xff0c;能给内容&#xff0c;尤其是图片&#xff0c;添加各种滤镜效果。 filter 滤镜详见博文&#xff1a;CSS3中强大的filter(滤镜)属性_css3滤镜_stones4zd的博客-CSDN博客 后续&#xff0c;CSS3 又新增了 backdrop-filter 背景滤镜。 backdr…

卷积概念理解

卷积(convolution)最容易理解的解释_一点一点的进步的博客-CSDN博客 图像处理之卷积模式及C实现_利用卷积模型分类图片 c_扫地工的博客-CSDN博客 卷积的重要的物理意义是&#xff1a;一个函数&#xff08;如&#xff1a;单位响应&#xff09;在另一个函数&#xff08;如&…

进程

目录 进程定义 进程与程序对比 进程分类 系统进程 用户进程 交互进程 批处理进程 守护进程 进程状态 进程组成 ​编辑正文段&#xff08;text&#xff09;和用户数据段 用户数据段 正文段 PCB进程控制块 进程标识信息 处理机状态 进程调度信息 进程控制信息 …

通达信自定义副图行业指标K线指标 HYZS_QD

行业指数:HY_INDEXC,NODRAW; DRAWKLINE(HY_INDEXH,HY_INDEXO,HY_INDEXL,HY_INDEXC); MA5:MA(HY_INDEXC,5),COLORWHITE; {MA10:MA(HY_INDEXC,10),COLORYELLOW,LINETHICK2}; DRAWTEXT_FIX(1,1,1,1,STRCAT(STRCAT(CON2STR(HY_INDEXADV,0),/),STRCAT(CON2STR(HY_INDEXDEC,0), ))),…

06_瑞萨GUI(LVGL)移植实战教程之驱动EC11旋转编码器(GPIO)

本系列教程配套出有视频教程&#xff0c;观看地址&#xff1a;https://www.bilibili.com/video/BV1gV4y1e7Sg 6. 驱动EC11旋转编码器(GPIO) 本次实验我们驱动EC11旋转编码器。 6.1 复制工程 上次实验得出的工程我们可以通过复制在原有的基础上得到一个新的工程。 如果你不清…

XCE18T4K1P40-FJJP40、F4Z1P40规格书(泰兴创航)

关于XCE18T4K1P40-FJJP40、F4Z1P40电连接器规格书 主要性能指标 工作温度&#xff1a;-55℃~200℃相对湿度&#xff1a;温度40℃2℃时达98%振动&#xff1a;频率10-2000Hz&#xff0c;加速度196m/s2冲击&#xff1a;加速度980m/s2机械寿命&#xff1a;5000次壳体材料&#xff1…

05_瑞萨GUI(LVGL)移植实战教程之添加LVGL库,对接显示和触摸驱动

本系列教程配套出有视频教程&#xff0c;观看地址&#xff1a;https://www.bilibili.com/video/BV1gV4y1e7Sg 5. 添加LVGL库&#xff0c;对接显示和触摸驱动 本次实验我们会融合前面实验的成果&#xff0c;添加LVGL库&#xff0c;对接显示和触摸驱动&#xff0c;让屏幕能显示…

金蝶云星空与泛微OA集成的方案落地与实践

打破信息孤岛&#xff0c;泛微OA集成的方案落地与实践 在现代企业内部&#xff0c;不同类型的业务系统和泛微OA平台层出不穷。企业需要找到一种高效的方法来整合和协同这些多样化的系统&#xff0c;同时将它们与泛微OA平台融合&#xff0c;以实现资源整合和高度协同的办公环境…

Win10下python的命令行启动和调用问题

Win10下python的命令行启动和调用问题 Win10下Python的启动问题解决办法 Win10下Python的启动问题 Win10下安装了python&#xff0c;但是命令行启动仍然显示Windows商店界面 同时在C:\Users\用户名\AppData\Local\Microsoft\WindowsApps目录下发现空的python3.exe文件 即便在…

【Java】基于SSM的单位人事管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…