仮想マシンのメモリの Active と Comsumed の動きを見る
Table of contents
はじめに:メモリの Active と Consumed の概要
vSphere には仮想マシンのメモリ使用量を測るカウンタとして Active (有効なゲストメモリ) と Consumed (消費) の2種類があります。
- Understanding the Memory Active and Memory Usage indicators on the Performance tab (1002604)
- Understanding vSphere Active Memory - VMware vSphere Blog
- メモリ (データ カウンタ)- vSphere の監視とパフォーマンス
仮想マシンのサイジングや性能監視などの際によく見られますが、それぞれ以下のメモリ使用量を測定しています。
- Active:直近で仮想マシンが積極的にアクセスしていたメモリ(統計値)
- Consumed:現在 ESXi が仮想マシンへ実際に割り当てている物理メモリ
メモリカウンタの動きを実験で見てみる
これらはゲストOS内から観測できるメモリ使用量とは観測対象が異なるため、OS のメモリ使用状況とは観測できる値も異なります。今回の記事では Linux ゲストでのページキャッシュの動作を一例として、仮想マシンのメモリの Active / Consumed の値がどのように変化するか見ていきたいと思います。
なお、Linux のページキャッシュの説明はしませんが、この辺りは @sat 様の YouTube チャンネルでの解説動画(その20~その26あたり)や書籍「[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識」が非常に分かりやすいと思います。
初期状態
Linux ゲストが起動された直後に実行した free コマンドの状態です。ゲストOSは仮想マシンに構成されているメモリ 8GB を認識しています。
1# free -h
2 total used free shared buff/cache available
3Mem: 7.6Gi 1.1Gi 5.7Gi 17Mi 806Mi 6.2Gi
4Swap: 1.6Gi 0B 1.6Gi
vSphere の仮想マシンのメモリ使用状況は以下のようになっています。VM Consumed の値から仮想マシンに概ね 2.6 GB の物理メモリが割り当てられており、パワーオンした時点では 8GB のメモリが全て割り当てられるわけではないことが分かります。
ESXi は仮想マシンが初めてメモリにアクセスしたタイミングで物理メモリを確保して割り当てます(2回目以降は同じ物理メモリを再利用)。ゲストOSが起動時点でいきなり全てのメモリ領域にアクセスしているわけではないので、仮想マシンの全てのメモリではなく一部だけがホストの物理メモリから実際に割り当てられています。
ゲストOSのページキャッシュを動作させる
ページキャッシュが動作した時の状況を確認するため、Linux ゲスト上で dd コマンドを実行して適当なダミーファイルを作ってみます。
1# dd if=/dev/zero of=/root/dummy01 bs=4M count=1000
2# dd if=/dev/zero of=/root/dummy02 bs=4M count=1000
改めて free コマンドを見ると buff/cache が増加しているので、ファイルがメモリ上にページキャッシュとしてキャッシュされたことが分かります。available の値は変わっていません。
1# free -h
2 total used free shared buff/cache available
3Mem: 7.6Gi 1.1Gi 118Mi 17Mi 6.3Gi 6.2Gi
4Swap: 1.6Gi 0B 1.6Gi
この時、vSphere の仮想マシンのメモリ使用状況は以下のようになっています。顕著に変わった点としては VM Consumed や Private が 8GB 近くまで、Active Guest Memory が約 4.6 GB まで増加しています。
先ほどの free コマンドの結果ではページキャッシュが利用されていました。これによりメモリがアクセスされているため、仮想マシンに新たに物理メモリが割り当てられ VM Consumed や Private の値が増加しています。VM Consumed は仮想マシンに割り当てられたメモリ、Private はその仮想マシンのみで使用されている(圧縮なども行われていない)メモリです。
Active Guest Memory は直近20秒間で仮想マシンが積極的にアクセスしたメモリ1を示しています。これも OS のページキャッシュによりメモリアクセスが発生しているので増加しています。あくまでも統計値で、本当に直近20秒間にアクセスが行われていたメモリ領域とは誤差が出る場合もあります。
ページキャッシュが機能した後に時間を置く
そのままゲストOSでは特に何もせず (OS 内のメモリ使用状況が変わらないように) 時間を置いてみます。すると、vSphere の仮想マシンのメモリ使用状況は以下のようになり、Active Guest Memory が 573 MB まで減りました。
先ほど Active Guest Memory が増加した要因は OS のページキャッシュによるものでした。しかし特に何もせず時間経過したことで、ページキャッシュで確保されたメモリ領域へのアクセスがなくなったことで、そのメモリ領域が Active でないと見なされ Active Guest Memory が減少したと考えることができます2。
OS 内でページキャッシュを解放してみる
OS 内でページキャッシュを解放した時の vSphere の仮想マシンのメモリ割り当ての状態を見てみます。
1# echo 3 > /proc/sys/vm/drop_caches
2# free -h
3 total used free shared buff/cache available
4Mem: 7.6Gi 1.1Gi 6.2Gi 17Mi 324Mi 6.3Gi
5Swap: 1.6Gi 0B 1.6Gi
OS 上では buff/cache が減り free が増加しました。しかし、vSphere の仮想マシンのメモリ割り当て状況を見ると VM Consumed や Private は変わっておらず、特に仮想マシンに割り当てられた物理メモリはホストに回収されていません。
ESXi のメモリ管理の仕様として、一度仮想マシンに物理メモリを割り当てた後は、原則としてそのメモリは回収されません(一部例外はあります)。ゲストOSが OS 見えのメモリ領域を解放したとしても、ESXi 側では仮想マシンに割り当てた物理メモリは回収せず、ゲストOSが再度同じメモリ領域を利用する場合には既に仮想マシンに割り当て済みの物理メモリが再利用されます。
メモリの Active と Consumed のまとめ
Active についてまとめると、
- 直近で仮想マシンが積極的にアクセスしていたメモリ(統計値)
- 実際にメモリアクセスが発生しているかどうかで増減する
Consumed についてまとめると、
- 現在 ESXi が仮想マシンへ実際に割り当てている物理メモリ
- 一度に全ては割り当てられず、ゲストOSの必要に応じて追加されていく
- (原則としては)仮想マシンに一度割り当てたら回収されることはない
サイジングや性能監視などで Active / Consumed を見る際はこの辺りの違いに注意が必要かなと思います。
なお、今回の記事の ESXi のメモリ管理の仕様は旧 ESX のメモリ管理のホワイトペーパーの主に1章~2章に記載されています。英語かつ古い資料ですが基本的な内容がよくまとまっているため、メモリ周りのサイジングやパフォーマンスチューニングなどに関わる場合は Performance Best Practices for vSphere x.x 等と合わせて一読をおすすめします。
参考1:仮想マシンのメモリはいつどうやって回収されるのか?
仮想マシンからホストの物理メモリを回収するための ESXi の機能としては主に以下があります。
- 透過的ページ共有(TPS)
同じデータのメモリ領域を共有して重複を排除します。既定では仮想マシン間の TPS は無効、仮想マシン内でのみメモリ共有が行われます。 - VMware Tools によるバルーン
VMware Tools に含まれるバルーンドライバが OS のページング/スワップ機能を利用してメモリを空け、空いた部分のメモリ領域をホストが回収します。 - 仮想マシンのメモリスワップ
ESXi が仮想マシンのメモリをホストキャッシュまたはスワップファイル)へ強制的に掃き出して回収します。ゲストOSのメモリアクセス状況は意識されません。 - メモリの圧縮
メモリを圧縮することでディスクにスワップされるメモリページを減らします。仮想マシンのメモリスワップと併用されます。
ESXi はメモリの圧迫状況をステータスとして持っており、high, clear (6.0 で追加), soft, hard, low の5種類が存在し、ステータスに応じて対応するメモリ回収機能が動作します。この記事では詳細は省きますが、ホワイトペーパーの 3.5 When to Reclaim Host Memory 節や以下のブログ記事あたりが参考になると思います。
What happens at which vSphere memory state? | Yellow Bricks
vSphere 6 ESXi memory states and reclamation techniques - Running-System.com
参考2:メモリ使用率に関連する vCenter Server のアラーム
ホストや仮想マシンのメモリ使用率を監視する時、多くの場合はまず以下の2つの事前定義済みアラームを見るかと思います。
- ホストのメモリ使用率 (Host memory usage)
- 仮想マシンのメモリ使用率 (Virtual machine memory usage)
これらはどちらも一定期間内のメモリの使用率をモニタリングしていますが、監視対象としているメトリックが異なります。前者は仮想マシンに割り当てられた物理メモリ(Consumed)の合計、後者は個々の仮想マシンの Active Guest Memory を監視しています。
このため、仮にある仮想マシンで物理メモリが全て割り当てられた(=VM Consumed が最大値)としても、Active Guest Memory がトリガー条件を満たしていなければ「仮想マシンのメモリ使用率」アラームはトリガーされないため注意が必要です。
参考3:vSphere DRS とメモリの Active / Consumed
vSphere 6.7 までの DRS は既定で Active Guest Memory をメモリのメトリックとして利用しており、vSphere 6.5 から追加された「ロード バランシングのメモリ メトリック」を有効にすると Consumed をメモリのメトリックとして利用するようになっていました。
- Load Balancing vSphere Clusters with DRS - VMware vSphere Blog
- クラスタ設定の編集 - vSphere のリソース管理
- What’s New in VMware vSphere 6.5
vSphere 7.0 では DRS の動作がホストの負荷から仮想マシンの負荷を見るように一新され、メモリのメトリックとしては Consumed を使用するようになっています(変更は不可)。