通过pprof界面查看到文件/函数级别的内存使用情况
在main.go 中加入如下代码: 这段代码参考了tarsgo https://github.com/TarsCloud/TarsGo 的框架代码
timeout := 600 //多久以后关闭profile
addr := localIP + port // 端口比如8080
go func() {
mux := http.NewServeMux()
mux.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index))
mux.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline))
mux.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
mux.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol))
mux.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace))
s := &http.Server{Addr: addr, Handler: mux}
go s.ListenAndServe()
time.Sleep(timeout)
s.Shutdown(context.Background())
}()
打开浏览器,输入http://节点所在的ip:8080/debug/pprof/heap,浏览器将会自动下载heap文件。
执行:
go tool pprof -http=":8082" heap 这里的heap就是刚才下载下来的heap文件名。
将会用浏览器打开界面:点击sample中的alloc_object

点击view中的source,将可以看到文件级别/函数级别的内存分配耗时

点击top,可以看到函数级别的耗时:

点击flat,top中的函数就会按照flat进行排序。
- flat的意思是:该函数自身(不包含函数调用其他函数)分配的堆上对象数量
- cum的意思是:该函数,包含函数调用其他函数分配的堆上对象数量
flat一定是<= cum的`
选择top中你关注的函数,比如第函数A,再点击view中的graph/flame graph,会显示出这个函数相关的调用关系
61***072(9.68%):表示函数本身执行了分配了这么多内存,占总alloc_object的9.68%
1815***553(28.37%):表示函数本身alloc_object+调用的子函数的alloc_objcct分配了1815***553个object,占总分配object的28.37%
同样,可以点击查看
alloc_space 分配空间大小
inuse_object 生成heap时,在用对象数
inuse_space 生成heap时,在用空间
通过benchmark -benchmem查看函数级别内存使用情况
go test -bench=. -benchtime=5s -benchmem
BenchmarkV1-8 50000 24833 ns/op 11491 B/op 115 allocs/op
BenchmarkV2-8 100000 14301 ns/op 4707 B/op 27 allocs/op
BenchmarkV3-8 50000 37850 ns/op 106496 B/op 19 allocs/op
第一列是函数名字+运行时对应的GOMAXPROCS的值,可以用-cpu=2来设置成其他的值
第二列是一种执行多少次
第三列是每次执行的耗时
第四列是每次执行需要分配的堆上内存空间大小
第五列是每次执行需要分配的堆上对象个数
golang 调优指标几乎都是针对堆,毕竟栈不是性能瓶颈
通过benchmark -memprofile查看代码级别内存使用情况
执行 go test -bench . -benchmem -memprofile prof.mem
看cpu使用情况的指令是go test -bench . -benchmem -cpuprofile prof.cpu`
执行go tool pprof -alloc_objects prof.mem 查看具体函数行分配的对象个数
看分配的内存空间大小是-alloc_space
在交互页面中,输入list 你被profile的函数名
(pprof) list MyFunction
ROUTINE ========================
766103 766103 (flat, cum) 7.09% of Total
……
39562 39562 184: list = make([]MyStruct, 0, 256)
. . 185: slotidIndex := 0
. . 186: for {
. . 187: if begin >= totalLen {
. . 188: break
. . 189: }
……
在184行,进行了39562个对象的分配,因为184行没有调用其它函数,所以flat和cum是相等的。
本文介绍如何使用pprof工具分析Go应用程序的内存使用情况,包括配置代码以启用pprof,通过浏览器获取heap文件,以及解析内存使用数据,理解flat和cum的区别,最后展示如何利用benchmark和memprofile进行深入的性能分析。
956

被折叠的 条评论
为什么被折叠?



