利用pprof排查内存泄漏
go技能卡:利用pprof排查内存泄漏
浅言碎语
前几天在POC环境,我负责的一个项目的调度程序内存出现线性增长,由于我们的常驻内存程序限制最大为256MB,所以增长超过这个限制的时候就会被kill掉。
明明DEV, TEST两个环境都是正确的,为啥POC就出现异常了呢?正当我们焦头烂额的时候,想起来我之前在程序里面已经开启了pprof数据采集服务,最终我们通过pprof找到问题位置,排查发现有一位同学在for循环开启了context之后没有关闭掉,使得内存一直增长,添加闭包之后得以解决。
关于pprof
pprof是提供应用运行状态(CPU, 内存,Goroutine, 锁等)数据和可视化分析的工具。目前pprof提供了两种方式
- runtime/pprof
- net/http/pprof
其实
net/http/pprof
本内部也是使用runtime/pprof
来实现,只不过是可以通过端口的方式暴露访问。本文主要讲述net/http/pprof
的使用方法。参考net/http/pprof。
使用
最简单的使用是在你的main函数里面导入
net/http/pprof
包,并监听一个端口号。
1 | package main |
让后在浏览器中访问链接:http://127.0.0.1:8080/debug/pprof/可以看到:
下面讲述一下上面几个参数的意义
| 类型 | 描述 |
| — | — | — |
| allocs | 内存分配情况的采样信息 |
| blocks | 阻塞操作情况的采样信息 |
| cmdline | 显示程序启动命令及参数 |
| goroutine | 当前所有协程的堆栈信息 |
| heap | 堆上内存使用情况的采样信息 |
| mutex | 锁争用情况的采样信息 |
| profile | CPU 占用情况的采样信息 |
| threadcreate | 系统线程创建情况的采样信息 |
| trace | 程序运行跟踪信息 |
说实话上面的信息打开后可读性不高,满屏密密麻麻的字符,不仔细看根本没法找到需要的信息,此时我们可以使用
go tool
命令来查看自己需要的信息。
1 | go tool http://127.0.0.1:8080/debug/pprof/指标 |
比如我们在cmd里面打开
go tool pprof http://127.0.0.1:8080/debug/pprof/allocs
,次数会进入待输入命令状态,如果想知道可以支持什么命令则可以输入help
即可查看, 进一步如果想看该命令释放方法可以help 命令
得到,比如下面输入help list
之后:
通常情况下我们会使用
top
/top10
/top20
来查看当前指数程序占用排行。
如果我们需要查看具体占用位置,可以输入
list 关键字
,比如list StartCPUProfile
:
此时我们就可以定位到问题了。
锦上添花
其实使用上面的方式我们已经定位到问题位置,但是命令行终究不够直观,如果提供一个文档或者网页能够把数据统计处理统计给我们,那岂不是妙哉,现饭还是很香的。我们只能想想,而大佬早已实现,其实
pprof
已经提供了网页方式浏览。我们只需要在上面的命令添加-web
即可。但是如果你是第一次使用,则会出现以下问题:
其实是提示我们需要安装
Graphviz
,Graphviz是一个由AT&T实验室启动的开源工具包,用于绘制DOT语言脚本描述的图形。我们需要安装一下,(下载地址)[https://graphviz.org/download/]。
安装之后重新执行
go tool pprof -web http://127.0.0.1:8080/debug/pprof/allocs
上面其实是在浏览器中打开文件,其实还有更好的一种方式,利用
pprof
起一个服务,可以实时看到指标信息, 执行go tool pprof -web http://127.0.0.1:8080/debug/pprof/allocs
:
你可以选择上面的
TOP
查看排行情况:
你还可以选择
Peek
查看调用详情:
其实还有很多功能,比如查看火焰图,查看当前数据和累计数据等。