一.pprof
- Profiling 是指在程序执行过程中,收集能够反映程序执行状态的数据。在软件工程中,性能分析(performance analysis,也称为 profiling),是以收集程序运行时信息为手段研究程序行为的分析方法,是一种动态程序分析的方法。
- GO中自带两个库可以进行程序分析调优:
1)runtime/pprof 对于本地只跑一次的程序,例如程序中的某一函数调优,调用 pprof 包提供的函数,手动开启性能数据采集。
2)net/http/pprof 对于在线服务,对于一个 HTTP Server,访问 pprof 提供的 HTTP 接口,获得性能数据。当然,实际上这里底层也是调用的 runtime/pprof 提供的函数,封装成接口对外提供网络访问。
一般常用net/http/pprof,操作相对简单
包含的性能数据
- allocs 和 heap 采样的信息一致,不过前者是所有对象的内存分配,而 heap 则是活跃对象的内存分配
二.net/http/pprof 使用
1)导包,启动端口服务
//只需要在你的程序中加入以下几行代码
import _ "net/http/pprof"
func maim() {
go func() {
http.ListenAndServe("0.0.0.0:8686", nil)
}()
}
原理
在初始化导包的时候,pprof 包会自动注册 handler,即我们调试过程中查看的接口:
func init() {
http.Handle("/debug/pprof/", http.HandlerFunc(Index))
http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
http.Handle("/debug/pprof/trace", http.HandlerFunc(Trace))
}
2)服务启动后,可以浏览器访问
http://127.0.0.1:8686/debug/pprof/
由于网页般数据可读性较差,服务器终端一般用命令行读取数据
# 下载 cpu profile,
go tool pprof http://47.93.238.9:8080/debug/pprof/profile
# 默认手机30S的数据,通过seconds调整时间120s
go tool pprof http://47.93.238.9:8080/debug/pprof/profile?seconds=120
# 下载 heap profile
go tool pprof http://47.93.238.9:8080/debug/pprof/heap
# 下载 goroutine profile
go tool pprof http://47.93.238.9:8080/debug/pprof/goroutine
# 下载 block profile
go tool pprof http://47.93.238.9:8080/debug/pprof/block
# 下载 mutex profile
go tool pprof http://47.93.238.9:8080/debug/pprof/mutex
3)输入上述命令后,会打开终端交互界面,交互常用命令 top、 list、 traces、 web
- top
获取前20条,cpu占用的函数
flat--- 该函数占时
flat% --- 该函数相对于总耗时的百分比
sum% --- 前面累计每一行flat 占比
cum --- 该函数以及该函数调用的其他函数总耗时
cum --- 对应的百分比
- list 具体函数: 如结合上图 list Eat 直接定位到消耗资源的代码处
- traces 列出函数的调用栈
实战中,首先通过profile,定位cpu消耗暂时较大的函数,然后通过heap定位内存占用较大的函数逻辑。
通过pprof定位性能瓶颈,根据实际问题优化,从而实现性能的提高
三.内存泄漏查找
内存分配既可以发生在堆上也可以在栈上。堆上分配的内存需要垃圾回收或者手动回收(对于没有垃圾回收的语言,例如 C++),栈上的内存则通常在函数退出后自动释放。
什么是内存泄漏
内存泄漏是指程序运行过程中已不再使用的内存,没有被释放,导致这些内存一直无法使用,直到程序结束这些内存才被释放的问题
一般形成主要有两个原因:
- goroutine 的阻塞
- GC回收时,无法实现100%的回收
怎么发现内存泄露
1、监控工具: 固定周期对进程内存占用采样,数据可视化后,根据内存占用走势(持续上升)
- 云平台的监控工具,或者建立一个脚本,定时执行采集数据
2、go pprof 间隔一段时间采集文件,对比分析是否存在明显的增量 对比heap
1)通过 go tool pprof http://47.93.238.9:8080/debug/pprof/heap 命令,在间隔一段时间后,分别获取两个文件;
2)go tool pprof -base file1 file2 对比两个文件,top获取对比后占用增加明显的函数块 对比goroutine
1)通过 go tool pprof http://47.93.238.9:8080/debug/pprof/goroutine命令,在间隔一段时间后,分别获取两个文件;
2)go tool pprof -base file1 file2 对比两个文件,top获取对比后占用增加明显的函数块
|
请发表评论