htop 和 golang readmemstats 之间的差异

Posted

技术标签:

【中文标题】htop 和 golang readmemstats 之间的差异【英文标题】:discrepancy between htop and golang readmemstats 【发布时间】:2016-03-29 15:04:04 【问题描述】:

我的程序在启动时加载了大量数据,然后调用 debug.FreeOSMemory() 以便立即归还任何额外空间。

loadDataIntoMem()
debug.FreeOSMemory()

加载到内存后,htop 会显示以下进程

 VIRT    RES     SHR
 11.6G   7629M   8000

但拨打runtime.ReadMemStats 会显示以下信息

Alloc         5593336608   5.3G
BuckHashSys   1574016      1.6M
HeapAlloc     5593336610   5.3G
HeapIdle      2607980544   2.5G
HeapInuse     7062446080   6.6G
HeapReleased  2607980544   2.5G
HeapSys       9670426624   9.1G
MCacheInuse   9600         9.4K
MCacheSys     16384        16K
MSpanInuse    106776176    102M
MSpanSys      115785728    111M
OtherSys      25638523     25M
StackInuse    589824       576K
StackSys      589824       576K
Sys           10426738360  9.8G
TotalAlloc    50754542056  48G
    Alloc 是从系统获得但尚未释放的数量(这是 常驻记忆对吗?)但两者之间存在很大差异。 我依靠 HeapIdle 来终止我的程序,即如果 HeapIdle 超过 2 GB,则重新启动 - 在这种情况下它是 2.5,并且即使在一段时间后也不会下降。 Golang 以后分配更多的时候应该使用 from heap idle,从而减少 heap idle 对吧? 如果假设 1 错误,哪个 stat 可以准确地告诉我 htop 中的 RES 值是多少。 如何降低 HeapIdle 的值?

这是在 go 1.4.2、1.5.2 和 1.6.beta1 上尝试过的

【问题讨论】:

我查看了memory decrease golang question,但它只说不依赖于 FreeOSMemory 或 runtime.GC(),我还能做什么? 正如a very skillful man 曾经说过的:"Premature optimization is the root of all evil."。分配了略低于 8 Gb 的物理内存和低于 12 Gb 的虚拟内存,您不必费心太多。提示:“过去分配的内存总和”和“当前使用的”是有区别的。 @JimB 我将大量数据存储在内存中以便更快地访问,并且由于我想避免让操作系统开始交换页面,因为其他进程也使用同一台服务器,所以我想杀掉当它进入不良状态时。顺便说一句 - 多久才能回到操作系统?十个小时过去了,HeapIdle 还是 2.5G。这似乎永远不会回到操作系统。 @AbhishekShivanna 你有没有找到它的底部?你能减少 HeapIdle 吗? 【参考方案1】:

您的程序的有效内存消耗将是Sys-HeapReleased。这仍然不会完全是操作系统报告的内容,因为操作系统可以根据程序的请求选择它认为合适的方式分配内存。

如果您的程序运行了相当长的时间,多余的内存将返回给操作系统,因此无需调用debug.FreeOSMemory()。保持内存尽可能低也不是垃圾收集器的工作。目标是尽可能有效地使用内存。这需要一些开销,并为将来的分配留出空间。

如果您在内存使用方面遇到问题,那么分析您的程序并了解为什么分配的内存超出预期会更有效率,而不是基于对内存的错误假设而终止您的进程。

【讨论】:

感谢您的解释。我获取并放入缓存,但为了避免锁的麻烦,我在给出值之前进行克隆。由于这个缓存有很多条目,所有这些克隆的创建和删除都给 gc 带来了负担。我想定期调用debug.FreeOSMemory(),因为我不希望操作系统开始交换页面,因为这会影响同一服务器上的其他进程。 @AbhishekShivanna:就像 FreeOSMemory 的文档说的那样,运行时在后台任务(称为堆清除器)中将内存返回给操作系统。使用当前设置可能需要 5-10 分钟。您可以通过运行 gctrace 来查看 GC 和 scavenger 发生了什么。

以上是关于htop 和 golang readmemstats 之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

Linux 命令 htop 的使用

htop 安装

CentOS Linux 系统工具htop和 glances安装和使用

CentOS Linux 系统工具htop和 glances安装和使用

htop命令使用详解

htop的安装与使用