一次 golang web 的内存分析
由于近期项目运行时,发现内存有一个规律性的增长。
首先排查的是 localcache 的问题,为了减少和 redis 的交互,对于一些热数据,同时更新频率也低,缓存周期内的数据延迟可以接受,采用了从 redis 读取到内存,进行二级缓存,缓存周期按数据量大小 为 30s 到 10mins 不等,适当的调小内存中的周期减少了一部分内存的开销。
这种内存占用毕竟占少数。需要分析其他占用。
用到的是 net/http/pprof 可在注册 http 路由时自定义,参考如下
path | api |
---|---|
/debug/pprof | pprof.Index |
/debug/pprof/cmdline | pprof.Cmdline |
/debug/pprof/profile | pprof.Profile |
/debug/pprof/symbol | pprof.Symbol |
/debug/pprof/trace | pprof.Trace |
在运行服务的机器上,安装分析工具(对 pprof 生成的文件进行分析)
yum install graphviz
安装成功后,启动服务,执行下述命令
go tool pprof ./mm-go localhost:1601/debug/pprof/heap
输入 top10 查看内存占用前 10 的函数
得到的响应如下
Fetching profile from http://localhost:8080/debug/pprof/heap
Saved profile in /root/pprof/pprof.mm-go.localhost:1601.alloc_objects.alloc_space.inuse_objects.inuse_space.006.pb.gz
Entering interactive mode (type "help" for commands)
(pprof) top10
12369.14kB of 12369.14kB total (100%)
Dropped 69 nodes (cum <= 61.84kB)
Showing top 10 nodes out of 23 (cum >= 512.02kB)
flat flat% sum% cum cum%
10320.21kB 83.44% 83.44% 10320.21kB 83.44% mm.com/priceServer.Worker.Start.func1.1
...
其中详细的数据如下表格
这样就能看到不同函数(func)占用内存大小以及占分配总内存的百分比了(flat)
flat | flat% | sum% | cum cum% | func |
---|---|---|---|---|
10320.21kB | 83.44% | 83.44% | 10320.21kB 83.44% | mm.com/priceServer.Worker.Start.func1.1 |
1024.41kB | 8.28% | 91.72% | 1024.41kB 8.28% | runtime.malg |
512.50kB | 4.14% | 95.86% | 512.50kB 4.14% | runtime.allocm |
512.02kB | 4.14% | 100% | 512.02kB 4.14% | runtime.rawstringtmp |
0 | 100% | 512.02kB 4.14% | encoding/json.(*decodeState).literal | |
0 | 100% | 512.02kB 4.14% | encoding/json.(*decodeState).literalStore | |
0 | 100% | 512.02kB 4.14% | encoding/json.(*decodeState).object | |
0 | 100% | 512.02kB 4.14% | encoding/json.(*decodeState).unmarshal | |
0 | 100% | 512.02kB 4.14% | encoding/json.(*decodeState).value | |
0 | 100% | 512.02kB 4.14% | encoding/json.Unmarshal |
根据提示查看内存占用较大的函数,来进行有针对性的优化