pprof
1 | heap profile: 13: 764144560 [139616: 4600982112] @ heap/1048576 |
764144560-258760704-207003648-165601280-54255616-43401216-34717696-196608-163840-18432-16384-8192-896-48=0
http://xxxx:8888/debug/pprof/heap?debug=1
1 | # runtime.MemStats |
结果分析:
sys
Sys 是下面列出的 XSys 字段的综合。Sys 维护着为 Go 运行时预留的虚拟内存空间地址,里面包含了:堆、栈,以及其他内部数据结构。
1 | Sys(72373071) = HeapSys(65994752)+ GCSys(2394112) + OtherSys(991083) + BuckHashSys(1616868)+ StackSys(1114112) + MSpanSys(196608) + MCacheSys(65536) |
HeapSys: 从操作系统获得的堆内存大小,虚拟内存空间为堆保留的大小,包括还没有被使用的
StackSys: 从操作系统取得的栈内存大小
MSpanSys: 从操作系统为mspan获取的内存字节数
MCacheSys: 从操作系统为mcache获取的内存字节数
BuckHashSys: 在profiling bucket hash tables中的内存字节数
GCSys: 垃圾回收元数据使用的内存字节数
OtherSys: off-heap的杂项内存字节数.
HeapSys
HeapSys:程序向应用程序申请的内存
HeapAlloc:堆上目前分配的内存
HeapIdle:堆上目前没有使用的内存
HeapReleased:回收到操作系统的内存
- HeapSys == HeapIdle + HeapInuse 代表了作为堆用途的内存空间。堆内存以Span为单元进行管理,从Span中分配内存给对象,分为Idle(没有分配对象)和Inuse(有对象)两种类型。
- HeapAlloc == Alloc 代表了堆上的未回收对象的实际占用空间(包括可回收部分)。注意,这和HeapInuse是有区别的。HeapInuse代表了分配对象的Span的大小,而HeapAlloc代表了实际对象的大小,因此可以认为一个是粗统计,一个是细统计,HeapAlloc <= HeapInuse
- StackSys 代表协程栈大小,其实是Stack Span的大小,可以和Idle Span互相转换。不同版本Go语言的最小协程栈大小是不同的,这次问题里面的协程栈大小为8K,因此30万协程2.4G,和图中的Stack部分相符,但还不足以解释剩下6G的堆内存占用量。
命令行pprof命令
查看30秒钟的CPU状态信息(执行后会卡30s,等就行了)
1 | go tool pprof http://localhost:6060/debug/pprof/profile |
查看堆状态信息
1 | go tool pprof http://localhost:6060/debug/pprof/heap |
-source 命令配置源码地址[可以定位到具体的代码行]
top,list 等常用命令
https://cloud.tencent.com/developer/section/1143647
https://www.dazhuanlan.com/2019/09/29/5d907f1435d79/
https://colobu.com/2019/08/28/go-memory-leak-i-dont-think-so
Go字符串的内存布局
https://blog.csdn.net/pplin/article/details/70241075
https://draveness.me/golang/datastructure/golang-string.html