ページフォールトとは?仮想記憶の仕組みと発生原因を図解で解説
応用情報技術者試験の仮想記憶分野では、「ページフォールト」が発生する仕組みと、それがなぜ性能低下(スラッシング)につながるのかがセットで問われます。「メモリが足りないとエラーになる」という漠然とした理解ではなく、OSがどう処理を継続させているのかまで押さえておきましょう。
ページフォールトとは何か
ページフォールト(Page Fault)とは、仮想記憶方式を採用したシステムにおいて、CPUがアクセスしようとしたページが主記憶(物理メモリ)上に存在しない場合に発生する例外(割り込み)のことです。
現代のOSはプログラムに「仮想アドレス空間」を見せており、実際のデータは仮想アドレスを一定サイズの「ページ」単位に分割して管理しています。すべてのページが常に主記憶に載っているとは限らず、一部は補助記憶装置(ディスク)上のスワップ領域に退避していることがあります。CPUがアクセスしようとしたページが主記憶上になかった場合、ハードウェアがページフォールトを検知してOSに処理を委ねます。
主記憶とキャッシュメモリの階層構造については、以前の記事「DRAMとSRAMの違いを図解」でも触れていますが、ページフォールトはさらに一段上の「主記憶とディスクの間」の階層で起きる現象だと捉えると位置づけが分かりやすくなります。
ページフォールト発生から処理完了までの流れ
ページフォールトが発生してから処理が再開されるまでは、次のようなステップで進みます。
- アドレス変換の失敗: CPUが仮想アドレスにアクセスする際、MMU(メモリ管理ユニット)がページテーブルを参照して物理アドレスに変換しようとするが、該当ページの「存在ビット(valid bit)」が
0になっている - 例外の発生: MMUがページフォールト例外を発生させ、CPUの制御がOSの例外ハンドラに移る
- ページインの実行: OSはどのプロセスのどのページが必要かを特定し、ディスク上のスワップ領域から該当ページを主記憶へ読み込む(ページイン)
- 空き領域の確保: 主記憶に空きがない場合、既存のページの中から追い出す対象を選び、必要であれば内容をディスクへ書き戻す(ページアウト)
- ページテーブルの更新: 読み込んだページの物理アドレスをページテーブルに登録し、存在ビットを
1に更新する - 命令の再実行: 例外の原因となった命令を最初からやり直す。今度はページがメモリ上にあるためアドレス変換に成功し、処理が継続する
CPUから見ると「アクセスしようとしたら一瞬中断され、気づいたら続きから動いている」ように見えますが、裏側ではディスクI/Oを伴う比較的重い処理が行われています。
ページフォールトの種類
ページフォールトは原因によって大きく2つに分類されます。
- マイナーフォールト(ソフトフォールト): ページが主記憶上には存在するが、そのプロセスのページテーブルにまだマッピングされていない場合に発生。ディスクI/Oが不要なため処理は軽い(例: 複数プロセスで共有されるライブラリのページに初めてアクセスする場合)
- メジャーフォールト(ハードフォールト): ページが主記憶上になく、ディスクからの読み込みが必要な場合に発生。ディスクI/Oが発生するため処理コストが大きい
試験対策としては「ページフォールト=即ディスクアクセスが発生する」と単純化せず、マッピングだけで済むケースもあるという点を押さえておくと、応用的な出題にも対応できます。
スラッシングという性能問題
ページフォールトの発生自体は仮想記憶の正常な動作の一部ですが、頻発しすぎると深刻な性能低下を招きます。これがスラッシング(Thrashing)です。
主記憶に対して同時に実行するプロセスの必要ページ数が多すぎると、あるページを読み込むために別のページを追い出し、そのページがすぐまた必要になって再度読み込む……という状態が繰り返されます。この状態になると、CPUは本来の処理よりもページの入れ替え(ページイン・ページアウト)に時間を取られ、システム全体のスループットが急激に低下します。
- 原因: 多重度(同時実行プロセス数)が主記憶容量に対して過大であること
- 対策: 多重度を下げる、主記憶を増設する、ワーキングセット(プロセスが直近で実際に使用しているページの集合)に基づいたページ管理を行う
試験では「スラッシングが発生している状況でさらに多重度を上げるとどうなるか」という因果関係を問う問題が定番です。多重度を上げるほどCPU使用率が上がると考えがちですが、スラッシング発生後は逆にCPU使用率(実処理に使われる割合)が下がっていく、という直感に反する挙動を理解しておく必要があります。
実務での関わり方
ページフォールトやスラッシングは低レイヤの概念に見えますが、実務のパフォーマンストラブルシューティングでも直接関わってきます。
- OOM Killerとの違いの理解: Linuxでメモリ不足が起きた際、スワップ領域があればまずページフォールトによるスワッピングで凌ごうとし、それでも足りない場合にOOM Killerがプロセスを強制終了します。「メモリが足りない=即座にプロセスが落ちる」わけではなく、スワップによる性能劣化を経由することが多いという段階を理解しておくと障害対応がしやすくなります
- Sparkやバッチ処理でのメモリ設計: データ処理基盤で実行メモリを小さく見積もりすぎると、OS側のスワップが多発してスラッシングに近い状態に陥り、処理が急激に遅くなることがあります。「メモリ使用量がわずかに超過しただけなのに処理時間が数倍になる」という現象は、スラッシングの典型的な兆候です
- コンテナのメモリ制限設計: Kubernetesなどでコンテナにメモリのlimitを設定する際、ホスト側にスワップが有効だとページフォールトを通じた性能劣化が予測しづらくなるため、多くの本番環境ではコンテナホストのスワップを無効化する運用が取られます
自分も業務でバッチジョブのメモリ設定を見直す際、vmstat コマンドで si(swap-in)・so(swap-out)の値を確認し、ページフォールトが頻発していないかをチェックすることがあります。CPU使用率だけを見ていると原因を見誤りやすい典型例です。
試験対策のポイント
応用情報技術者試験でページフォールトが問われる際は、以下の観点が狙われやすいです。
- ページフォールトが発生する条件(アクセス先ページが主記憶上に存在しない)
- 発生から処理再開までの流れ(例外発生 → ページイン/アウト → ページテーブル更新 → 命令再実行)
- マイナーフォールトとメジャーフォールトの違い
- スラッシングが起きる原因(多重度過多)と、多重度を上げた際のCPU使用率の変化
- スラッシングへの対策(多重度の調整、主記憶増設、ワーキングセットの活用)
「ページフォールト=異常」ではなく「仮想記憶を成立させるための正常な仕組み」であり、それが過剰に発生した状態がスラッシングという性能問題である、という因果の流れをセットで説明できるようにしておくのがポイントです。
まとめ
ページフォールトは、CPUがアクセスしようとしたページが主記憶上に存在しない場合にOSがディスクから該当ページを読み込み、処理を継続させるための仮想記憶の基本的な仕組みです。この仕組み自体は正常な動作ですが、主記憶に対して同時実行プロセスの必要ページ数が過大になるとスラッシングという深刻な性能低下を招きます。試験対策としては発生の流れと種類の違いを、実務としてはスワップ多発の兆候をどう見抜くかを押さえておくと、仮想記憶の理解が一段深まります。