2

我的程序在启动时加载了大量数据,然后调用 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
  1. Alloc 是从系统获得的尚未释放的数量(这是常驻内存对吗?)但两者之间存在很大差异。
  2. 我依靠 HeapIdle 来杀死我的程序,即如果 HeapIdle 超过 2 GB,则重新启动 - 在这种情况下它是 2.5,并且即使在一段时间后也不会下降。Golang 将来分配更多时应该使用 from heap idle,从而减少 heap idle 对吗?
  3. 如果假设 1 是错误的,哪个 stat 可以准确地告诉我 htop 中的 RES 值是多少。
  4. 我能做些什么来降低 HeapIdle 的价值?

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

4

1 回答 1

1

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

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

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

于 2015-12-23T14:16:15.603 回答