我编写了一个golang程序,该程序在运行时使用1.2GB的内存。
调用
- 其余的内存使用情况又如何呢?
- 有没有更好的工具来解释golang运行时内存?
使用
..和此堆表单配置文件:
这是我的代码:https://github.com/sharewind/push-server/blob/v3/broker
堆配置文件显示活动内存,运行时认为该内存已被go程序使用(即:垃圾收集器尚未收集)。当GC确实收集内存时,配置文件会缩小,但是不会有内存返回给系统。您将来的分配将尝试在请求系统提供更多信息之前使用先前收集的对象池中的内存。
从外部看,这意味着您程序的内存使用量将增加或保持不变。外部系统显示为程序的"驻留大小"的是分配给程序的RAM字节数,无论它是保存使用中的值还是收集的值。
这两个数字经常有很大差异的原因是:
如果要准确了解Go如何查看内存,可以使用运行时。ReadMemStats调用:http://golang.org/pkg/runtime/#ReadMemStats
或者,由于您正在使用基于Web的配置文件,如果可以通过以下浏览器访问配置文件数据:
runtime.MemStats文档(http://golang.org/pkg/runtime/#MemStats)提供了所有字段的说明,但有趣的是:
- HeapAlloc:本质上是探查器为您提供的内容(活动堆内存)
- Alloc:与HeapAlloc类似,但全部用于托管内存
- Sys:操作系统请求的内存总量(地址空间)
Sys与操作系统报告之间仍然存在差异,因为Go对系统的要求以及操作系统提供的内容并不总是相同的。另外,go不会跟踪CGO / syscall(例如:malloc / mmap)内存。
简而言之,作为@Cookie of Nine答案的补充:您可以尝试
通过
我一直对Go应用程序的驻留内存不断增长感到困惑,最后我不得不学习Go生态系统中存在的性能分析工具。运行时在运行时.Memstats结构中提供了许多指标,但是可能很难理解其中哪些指标可以帮助找出内存增长的原因,因此需要一些其他工具。
分析环境
在您的应用程序中使用https://github.com/tevjef/go-runtime-metrics。例如,您可以将其放在
在
设置
从https://grafana.com导入仪表板#3242(Grafana主页->左上角->仪表板->导入):
最后,启动您的应用程序:它将运行时指标传输到统一的
内存消耗分析
1
2
3
4 HeapIdle minus HeapReleased estimates the amount of memory
that could be returned to the OS, but is being retained by
the runtime so it can grow the heap without requesting more
memory from the OS.
对于那些试图调查内存消耗问题的人,我建议按照所述步骤进行操作,以排除一些琐碎的错误(例如goroutine泄漏)。
显式释放内存
有趣的是,通过显式调用
实际上,与默认条件相比,此方法节省了大约35%的内存。
您还可以使用StackImpact,它会自动记录常规和异常触发的内存分配配置文件并将其报告给仪表板,这些配置文件以历史记录和可比较的形式提供。有关更多详细信息,请参见此博客文章。Production Go应用程序中的内存泄漏检测
免责声明:我为StackImpact工作