介绍一下背景
今天有同学反应有个golang的服务内存占用比较大需要扩下容,监控看了下内存占用超过1G,觉得挺有意思的可以分析分析,在我写过的golang服务里面很少有内存占用比较大的,另外这个服务在我看来应该是比较简单的不至于用到这么多的内存。那就分析分析怎么对golang的程序内存进行分析
Go官方提供了很好的性能分析工具pprof
使用方式只需要在入口处添加以下:
import _ "net/http/pprof"
go func() {
http.ListenAndServe("0.0.0.0:8080", nil)
}()
这里会在本地开启一个http的服务,打开浏览器查看 http://localhost:8080/debug/pprof/
可看到协程数,同步数,堆和线程创建数
命令交互式
--inuse_space 程序常驻内存的占用情况
go tool pprof -inuse_spacehttp://localhost:8080/debug/pprof/heap
--alloc_objects 内存的临时分配情况
go tool pprof -alloc_space http://localhost:8080/debug/pprof/heap
-top 占用排行 top10 top20
-cum: 将函数调用关系数据进行累积计算
-- 生成图片 (需要安装graphviz eg. apt install graphviz)
go tool pprof -alloc_space -cum -svg http://localhost:8080/debug/pprof/heap > heap.svg
-- 直观查看火焰图等
可以通过本地浏览器http://localhost:8000 直观的看到火焰图、调用图
go tool pprof -http=:8000 http://localhost:8080/debug/pprof/profile
go tool pprof -http=:8000 profile.out (通过http://localhost:8080/debug/pprof/profile获取的采样文件点或点击profile,程序会开始进行半分钟(默认值)的CPU采样,然后才会下载文件。)
go tool pprof -http=:8000 pprof.pb.gz
指标
flat flat%
一个函数内的directly操作的物理耗时。例如
func foo(){
a() // step1
largeArray := [math.MaxInt64]int64{} // step2
for i := 0; i < math.MaxInt64; i++ { // step3
c() // step4
}
}
flat只会记录step2和step3的时间;flat%即是flat/总运行时间。内存等参数同理。
所有的flat相加即是总采样时间,所有的flat%相加应该等于100%。
cum cum%
相比flat,cum则是这个函数内所有操作的物理耗时,比如包括了上述的step1、2、3、4。
cum%即是cum的时间/总运行时间。内存等参数同理。
sum%
其上所有行的flat%的累加。可以视为,这一行及其以上行,其所有的directly操作一共占了多少物理时间。
参考:
[1] https://zhuanlan.zhihu.com/p/396363069
[2] https://cloud.tencent.com/developer/article/1489186
[3] https://blog.csdn.net/kenkao/article/details/96300389