このエントリは2021/06/01現在の情報に基づいています。将来の機能追加や変更に伴い、記載内容との乖離が発生する可能性があります。
先日、以下のような問い合わせをもらった。
現在Azure MonitorのLog Analyticsパフォーマンスカウンターを使ってLinux VMのメモリ使用量(Used Memory MBytes)をチェックしているのだが、VMにログインして
free
を実行して取得した値(used)と大きなずれがある。これはなぜなのか?
Log Analyticsのパフォーマンスカウンターとは以下のことを指している。
Log Analytics エージェントを使用して Windows と Linux のパフォーマンス データ ソースを収集する / Collect Windows and Linux performance data sources with Log Analytics agent
https://docs.microsoft.com/azure/azure-monitor/agents/data-sources-performance-counters

free
コマンドはご存知の通り。

上の例でも、Log Analyticsのパフォーマンスカウンターで出力したUsed Memory MBytes(677 MiB)とfreeで出力したusedの値(369 MiB)が異なっていることがわかる。
違いの理由
両者とも計算のための値は /proc/meminfo
から取得しているが、計算式が異なるために、パフォーマンスカウンターの値とfree
で取得した値が異なる。以下はUbuntu 18.04の/proc/meminfoの例。対比のため、ほぼ同じタイミングでfreeコマンドを実行してみた。

Log Analyticsのパフォーマンスカウンター
Used Memory MBytesは以下の計算式で求めている。
UsedMemory = MemTotal - MemAvailable
上の例で言うと、
UsedMemory = 8,152,804 - 7,457,416
= 695,388 (KiB)
= 678 (MiB)
パフォーマンスカウンターのUsed Memory MBytesとして収集した値は678 (MiB) で、上の計算式の値と一致する(当然ではある)。

freeコマンド
free
コマンドで出力される値は計算式が明記されている。
Interpreting /proc/meminfo and free output for Red Hat Enterprise Linux
https://access.redhat.com/solutions/406773
Ubuntu Manpage: free – Display amount of free and used memory in the system
https://manpages.ubuntu.com/manpages/bionic/man1/free.1.html
今回Ubuntu 18.04をこの動作確認に使っているが、Ubuntu 18.04の場合、used
の計算式は以下のようである。1番目はfree
コマンドで出力される値を用いる場合の計算式で、2番目は/proc/meminfo
の値から算出する場合の計算式である。
used = total - free - buffers - cache
= (MemTotal + SwapTotal) - (MemFree + SwapFree) - (Buffers) - (Cached + SReclaimable)
明らかにパフォーマンスカウンターと計算式が違うので、算出値も異なることは容易に想像できるが、実際に算出してみる。
used = total - free - buffers - cache
= (MemTotal + SwapTotal) - (MemFree + SwapFree) - (Buffers) - (Cached + SReclaimable)
= (8,152,804 + 0) - (5,842,952 + 0) - 112,500 - (1,591,036 + 225,580)
= 380,736 (KiB)
= 371 (MiB)
計算した結果は371 (MiB)で、(上のスクリーンショットにある)free
コマンドで得た値と(当然ながら)一致する。
結論
同じusedという表現を使っていても、計算式が異なるため同じ値にはならない。そのため実際に利用する場合には注意しておく必要がある。
なお、ドキュメントに記載の通り、パフォーマンスカウンターの収集インターバルの最小値は10秒である。そのため、free
コマンドをオンデマンドで実行するのと厳密に同じタイミングで収集できるわけではない点は考慮しておく必要がある。
Linux パフォーマンス カウンター / Linux performance counters
https://docs.microsoft.com/azure/azure-monitor/agents/data-sources-performance-counters#linux-performance-counters