我正在用 Go 编写一个依赖于正则表达式的程序。htop 中显示的内存使用量正在稳步增加,直至程序崩溃。(> 5-7GB)
然而,当我用 pprof 分析内存使用情况时,它告诉我实际上只有一小部分在使用。(~70MB)
我尝试手动触发 GC:
go func() {
for range time.Tick(30*time.Second){
runtime.GC()
debug.FreeOSMemory()
runtime.ReadMemStats(&m)
fmt.Printf("HeapSys: %d, HeapAlloc: %d, HeapIdle: %d, HeapReleased: %d\n", m.HeapSys, m.HeapAlloc,
m.HeapIdle, m.HeapReleased)
}}()
// Sample output(not from the same run as the other numbers):
// HeapSys: 347308032, HeapAlloc: 123637792, HeapIdle: 194322432, HeapReleased: 0
这显示没有效果。我的理解是golang只在需要更多内存时才请求内存,并且每隔一段时间清理一次(使用GCTRACE运行表明gc实际上经常运行)我不明白为什么golang在实际使用的内存相对较小时继续请求内存.
有人知道差距的根本原因以及如何防止我的程序吃掉内存吗?
由于图表是 SVG,我无法嵌入它们:
- pprof inuse_space https://files.niels-ole.com/memory9.svg(可接受的内存使用)
- pprof alloc_space https://files.niels-ole.com/memory9-alloc.svg(通常称为分配大量内存的正则表达式)
可能相关: 如何分析golang内存 没有解释为什么内存不断增加(并且没有被重用)。