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 つには大きな違いがあります。
  2. 私は自分のプログラムを強制終了するために HeapIdle に依存しています。つまり、HeapIdle が 2 GB を超えている場合は再起動します。この場合は 2.5 で、しばらくしてもダウンしません。Golang は、将来さらに割り当てるときに from heap idle を使用して、heap idle を減らす必要があります。
  3. 仮定 1 が間違っている場合、どの統計が htop の RES 値が何であるかを正確に教えてくれます。
  4. HeapIdle の値を減らすにはどうすればよいですか?

これはgo 1.4.2、1.5.2、および1.6.beta1で試行されました

4

1 に答える 1

1

プログラムの実効メモリ消費量は になりますSys-HeapReleased。OS は、プログラムの要求に基づいて適切と思われる方法でメモリを割り当てることを選択できるため、これは OS が報告する正確なものではありません。

プログラムがかなりの時間実行された場合、余分なメモリが OS に戻されるため、 を呼び出す必要はありませんdebug.FreeOSMemory()。また、メモリをできるだけ低く保つこともガベージ コレクタの仕事ではありません。目標は、メモリをできるだけ効率的に使用することです。これには、いくらかのオーバーヘッドと、将来の割り当てのための余地が必要です。

メモリの使用に問題がある場合は、メモリに関する誤った仮定に基づいてプロセスを強制終了するのではなく、プログラムをプロファイリングして、予想以上に多くを割り当てている理由を確認する方がはるかに生産的です。

于 2015-12-23T14:16:15.603 に答える