【入門編】 メモリ仮想化における物理アドレスと仮想アドレスの2重変換 – クラウドインフラと仮想化ネットワーク実践ガイド

こんにちは!技術メディアのナビゲーターであり、日々クラウドやインフラの裏側をパケットレベルで追いかけているSREの「アキラ」です。

AWSやGoogle Cloud、あるいは手元のVirtualBoxやVMwareを使って「仮想マシン(VM)」を立ち上げたことがある方は多いのではないでしょうか。ボタンをポチッと押すだけで、まるで本物のパソコンがそこにあるかのようにOSが立ち上がる……本当に魔法のような技術ですよね。

しかし、その魔法の裏側では、コンピュータの心臓部である「メモリ」をめぐる、非常に泥臭くも芸術的な「住所変換のドラマ」が繰り広げられているのです。

特に、仮想マシンのメモリ管理で必ず登場する「ゲスト仮想アドレス(GVA)」「ゲスト物理アドレス(GPA)」「ホスト物理アドレス(HPA)」という3つの言葉。これらが絡み合う「2重のメモリ変換」は、多くの初学者が「うっ、難しそう……」と目を背けたくなる難所です。

でも、安心してください!今回はこの複雑なメモリの2重変換のメカニズムを、難しいビット計算や英語の仕様書を一切使わず、「郵便配達の流れ」や「マンションの部屋割り」といった身近な例え話を使って、一歩ずつ丁寧に紐解いていきます。

読み終わる頃には、「なんだ、仮想化のメモリってこういうことだったのか!」とスッキリ納得できているはずです。それでは、一緒に学んでいきましょう!

—

1. 基本のキ:そもそも「メモリのアドレス変換」ってなぜ必要なの?

仮想マシンの話に入る前に、まずは「仮想化をしていない普通のパソコン(物理マシン)」が、どうやってメモリを扱っているかをおさらいしておきましょう。

アプリケーションは全員「自分専用のパラダイス」に住んでいる

パソコンの中で動くGoogle ChromeやLINEなどのアプリ(プロセス)は、実はみんな「このパソコンのメモリは、全部自分だけのものだ!」と勘違いして動いています。

もし、アプリたちが本物の物理的なメモリ(メモリカードの金色の端子に直結した住所)をそのまま触れてしまったらどうなるでしょう?
Chromeが使っているメモリの場所に、LINEがうっかりデータを上書きしてしまい、システムがクラッシュしてしまいますよね。

そこで、OS(WindowsやLinuxなど)は、アプリたちに「仮想アドレス(Virtual Address)」という「ハリボテの住所(バーチャルなメモリ空間)」を見せています。

  • アプリが見ている世界:「0番地から100番地までは、全部僕専用のスペースだ!」(仮想アドレス)
  • 本物のメモリの世界:「実際は、スカスカのあちこちにバラバラに保存されているよ」(物理アドレス)

OSは、この「ハリボテの住所」と「本物の住所」を対応させる「住所録(ページテーブル)」をこっそり作り、CPUに翻訳させているのです。

—

2. 仮想化の世界へようこそ!登場人物が「2倍」になる大混乱

さて、ここからが本題です。この物理マシンの中に、さらに「仮想マシン(VM)」を作るとどうなるでしょうか?

仮想マシンの中には、さらに「ゲストOS(VMの中で動くOS)」が動いていますよね。
ゲストOSは、自分が仮想マシンだとは夢にも思っていません。「自分がこのパソコンを支配している!」と思い込んでいます。

そのため、仮想マシンの世界では、住所録がなんと「2重」に必要になってしまうのです。

ここで登場するのが、以下の3つのアドレス(住所)たちです。

1. ゲスト仮想アドレス(GVA: Guest Virtual Address)

  • 仮想マシンの上で動く「アプリ(Chromeなど)」が見ているハリボテの住所。

2. ゲスト物理アドレス(GPA: Guest Physical Address)

  • 仮想マシンの中の「ゲストOS」が、「これが本物のメモリチップの住所だ!」と思い込んでいる住所。

3. ホスト物理アドレス(HPA: Host Physical Address)

  • サーバー(ホストマシン)に刺さっている、正真正銘、本物のメモリチップの物理的な住所。

物理マシンの時は「仮想 ➔ 物理」の1回だけで済んだ翻訳が、仮想マシンの世界では、

「GVA(ゲストのアプリ)」 ➔ 「GPA(ゲストOSの勘違い)」 ➔ 「HPA(本物のメモリ)」

という、2重の変換(アドレス翻訳)を行わなければならなくなったのです!

—

3. 郵便配達に例えてみよう!「2重変換」の分かりやすい仕組み

言葉だけだと頭がこんがらがってしまいますよね。ここで、現実世界の「シェアハウスの郵便配達」に例えて考えてみましょう。

あなたが、ある大きなシェアハウス(ホストマシン)の「201号室(仮想マシン)」に住んでいると想像してください。

【現実世界の住所(HPA)】
東京都千代田区1-1 シェアハウス「クラウド館」
    │
    ▼
【部屋番号(GPA)】
201号室(ゲストOSが管理する空間)
    │
    ▼
【机の引き出し(GVA)】
引き出しA(アプリが直接データを置く場所)
  • ゲスト仮想アドレス(GVA):

あなたが自分の部屋(201号室)の中で、「机の右から2番目の引き出し」と決めている場所です。

  • ゲスト物理アドレス(GPA):

シェアハウスの管理人が決めた、あなた宛ての荷物を置く「201号室のレターボックス」です。

  • ホスト物理アドレス(HPA):

郵便局員がバイクで配達してくる、日本政府が認めた本物の住所「東京都千代田区1-1」です。

荷物が届くまでの「2重変換」のドラマ

あなたがネットショッピングで買い物をしました。荷物を部屋の「机の引き出し(GVA)」にしまいたいとします。

1. 第1の変換(GVA ➔ GPA):
まず、あなた(アプリ)は「机の引き出し(GVA)」に荷物を入れたいのですが、部屋の中のルールとして、一度「201号室のレターボックス(GPA)」を経由して整理する必要があります。
2. 第2の変換(GPA ➔ HPA):
しかし、郵便局員(CPU)は「201号室」だけでは日本中のどこにあるか分かりません。「東京都千代田区1-1(HPA)」という本物の住所に翻訳して初めて、トラックで荷物を運ぶことができます。

このように、仮想マシンの中でデータを1回読み書きするたびに、裏側では「あなたが指定した引き出しは、201号室のことで、それはつまり千代田区1-1のあの場所だ!」という、2つの住所録を交互にめくるような、とても面倒な作業が発生しているのです。

—

4. この重労働を救う、CPUの超能力「EPT / NPT」

もし、この2重の翻訳をすべてソフトウェア(ハイパーバイザー)の力だけで力ずくで行おうとすると、メモリを読み書きするたびに動作がガクッと重くなってしまいます。昔の仮想化ソフトが遅かったのは、まさにこれが原因でした。

そこで、IntelやAMDといったCPUのメーカーは、この翻訳を「CPUのハードウェアパワーで、一瞬で片付ける仕組み」を開発しました。

  • Intel製CPUの場合: EPT(Extended Page Tables:拡張ページテーブル)
  • AMD製CPUの場合: NPT(Nested Page Tables:入れ子ページテーブル)

これは、郵便局(CPU)が「201号室の引き出しA = 東京都千代田区1-1の、この座標!」という一発翻訳の『スーパー直通住所録』をハードウェアの中に自動で作り、超高速で処理してくれる機能です。現代のクラウドや仮想化システムは、このハードウェアの力のおかげで、物理マシンとほぼ変わらない爆速なメモリスピードを実現できているのですね。

—

5. 実践・確認編:Linux/KVM環境でメモリ仮想化の仕組みを見てみよう!

ここからは少しだけエンジニアらしく、実際のLinux環境(KVMという仮想化技術を使っている場合)で、この「高速化の仕組み(EPT)」が有効になっているかを確認する方法をご紹介します。

また、メモリの2重変換の負担をさらに軽くするための、現場でよく使われるプロの設定(HugePages:巨大ページ設定)も見てみましょう!

① EPT(Intelの高速変換機能)が有効か確認する

あなたのLinuxサーバーで、この「住所変換を爆速にする機能(EPT)」がちゃんと動いているかは、以下のコマンドで確認できます。

# IntelのCPUで EPT が有効になっているかを確認するコマンド
# (1 が出力されれば、有効になっており、爆速で2重変換が行われています)
cat /sys/module/kvm_intel/parameters/ept

② 住所録をスリムにする魔法「HugePages(ヒュージページ)」の設定

郵便配達の例えを思い出してください。
「100万個の小さな荷物」を、1個ずつ細かい住所で届けるのは大変ですよね。それなら「大きめのダンボール(巨大なページサイズ)」にまとめて届ければ、住所録のページ数自体をグッと減らすことができます。

Linuxでは、通常 4KB という小さな単位でメモリを管理していますが、これを 2MB や 1GB という巨大な単位にする仕組みを HugePages と呼びます。これを使うと、2重変換の住所録が劇的にスリムになり、VMのパフォーマンスが向上します。

以下は、Linuxで 2MB のHugePagesを1024枚(合計2GB分)確保する設定例です。

# 1. 一時的にHugePages(2MB)を1024枚確保するコマンド
sudo sysctl -w vm.nr_hugepages=1024

# 2. 仮想マシン(KVM)にHugePagesを割り当てるための設定例
# 設定ファイル(/etc/sysctl.conf)に記述して、起動時に毎回有効にする設定です
sudo tee -a /etc/sysctl.conf << 'EOF'

# --- SREチーム推奨: メモリ2重変換の負荷を下げるためのHugePages設定 ---
# 2MBのメモリページを1024枚(合計2GB)確保し、アドレス変換のオーバーヘッドを削減します
vm.nr_hugepages = 1024
EOF

# 3. 設定を反映させる
sudo sysctl -p

この設定を行うことで、ハイパーバイザーは巨大なメモリの塊をVMに直接ドカンと渡せるようになり、あのややこしい「GVA ➔ GPA ➔ HPA」の翻訳回数を劇的に減らすことができるようになります。

—

まとめ:一歩ずつ、インフラの深淵へ

最後に、今回学んだことをおさらいしておきましょう!

  • 仮想化の世界では、アプリが見る住所(GVA)、ゲストOSが思い込む住所(GPA)、本物の住所(HPA)の「3つの住所」が存在する。
  • この間を取り持つために「2重のアドレス変換」という複雑なプロセスが発生している。
  • この翻訳の負担を減らすために、CPUには EPT/NPT という「スーパー直通住所録」が備わっている。
  • さらに実務では、HugePages を使うことで、住所録そのものをコンパクトにして高速化を図っている。

一見すると難解なクラウドインフラや仮想化ネットワークも、こうして「誰が誰に、どうやってデータを届けているのか」を順を追って見ていけば、とても人間味のある面白い仕組みであることが分かりますよね。

あなたが普段何気なく起動しているその仮想マシンの裏側で、CPUとOSが必死に「郵便配達」をしてくれている姿を、ぜひ想像してみてください。

インフラの世界は、知れば知るほど面白い発見に満ちています。これからも一歩ずつ、一緒に楽しんで学んでいきましょう!

コメント

タイトルとURLをコピーしました