TL

デマンドページングとページフォルト処理

プログラムが必要としたページだけを実際に触れた瞬間に読み込む仕組みと、ページフォルトでカーネルが何を判定し何を埋めるのかを、マイナー・メジャーの分岐から内部動作で理解できます。

応用デマンドページングページフォルト仮想記憶readaheadメモリ管理OS最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.デマンドページングは、メモリ確保時には物理ページを割り当てず、最初にアクセスされた瞬間のページフォルトで初めて中身を埋める遅延戦略。起動とメモリ使用量を抑える。
  • 2.フォルトは、I/Oを伴わず既存ページに繋ぐだけのマイナーフォルトと、ディスクからの読み込みが要るメジャーフォルトに分かれる。性能を支配するのは後者の回数。
  • 3.ハンドラはVMA照合で正当性を確認し、匿名・ファイル・スワップ・CoWの別に分岐して物理ページを用意する。先読み(readahead)でメジャーフォルトをまとめて減らす。

デマンドページングとは:確保と居住の分離

mmapmalloc でメモリを確保しても、その瞬間に物理ページが割り当てられるわけではありません。カーネルがやるのは、プロセスの仮想アドレス空間に どの範囲が何の用途か を記述した区間(Linux でいう VMA, virtual memory area)を登録するだけです。物理メモリ(フレーム)は そのページに実際にアクセスした瞬間 に初めて与えられます。これが デマンドページング(demand paging) で、「要求があってから(on demand)載せる」遅延戦略です。

狙いは二つあります。第一に 起動が速い:実行ファイルが数十 MB あっても、最初に触れる数ページだけ読み込めば動き出せます。第二に メモリを節約できる:確保したが一度も触らない領域には物理ページが付かないため、malloc の予約と実使用の差がメモリを食いません。鍵となるのは、ページテーブルのエントリ(PTE)を 「無効(not present)」 のままにしておき、CPU のアクセスでわざと例外を起こさせる点です。

仮想アドレスの予約と物理ページの居住は別物

仮想空間に区間を確保することと、物理ページが住み着く(resident になる)ことは別レイヤーの操作です。RSS(resident set size)が確保量より小さいのはこのため。デマンドページングは「予約は安く、居住は必要になってから」を徹底する仕組みです。

ページフォルトの発生:ハードウェアからハンドラへ

CPU が仮想アドレスを物理アドレスへ変換しようとして、対応する PTE が無効、または許可されていないアクセス(読み取り専用ページへの書き込みなど)だった場合、MMU は ページフォルト例外 を上げます。これは同期例外(フォルト)で、命令の途中で発生し、原因を解決すれば 同じ命令をやり直せる ように設計されています。

ハードウェアはフォルト時に、フォルトを起こした アドレス(x86 なら CR2 レジスタ)と、エラーコード(読み/書き、ユーザ/カーネル、存在しない/権限違反 の別)をカーネルに渡します。カーネルのページフォルトハンドラはこれを入口に処理を始めます。アドレス変換の前提は 仮想記憶のアドレス変換とMMU/TLBの内部 を参照してください。

ハンドラの最初の仕事は 正当性の判定 です。フォルトアドレスがプロセスのどの VMA に属するかを探し、その VMA に記録された許可(読み/書き/実行)と照合します。ここで二つに分かれます。

  • VMA が存在し、アクセスが許可と矛盾しない → 正当なフォルト。物理ページを用意して PTE を埋め、命令を再実行させる。
  • VMA が無い、または許可違反(読み取り専用への書き込みで CoW でもない、実行不可領域の実行など)→ 不正アクセス。ユーザ空間なら SIGSEGV を送る。
フォルト=バグ、ではない

ページフォルトは正常動作の一部です。デマンドページングでは「まだ載せていないページに初めて触れた」だけでフォルトが起き、ハンドラが粛々と埋めます。異常なのは VMA に属さないアドレスや権限違反のフォルトだけで、これが SIGSEGV になります。両者を混同しないことが内部理解の第一歩です。

マイナーフォルトとメジャーフォルト

正当なフォルトは、ディスク I/O を伴うか否か でさらに二分されます。この区別が性能を支配します。

種類条件コスト代表例
マイナーフォルト必要なデータは既にメモリ上にある。PTEを繋ぐだけ数百ナノ秒〜(CPU処理のみ)ゼロページの割当、共有済みファイルページへの新規マップ、CoW複製
メジャーフォルトデータをストレージ(スワップ/ファイル)から読む必要がある数十マイクロ〜ミリ秒(I/O待ち)未ロードのファイルページ、スワップアウト済みページの復帰

マイナーフォルト(minor / soft fault) は、解決に必要なページがすでに物理メモリのどこかに居る場合です。たとえば他プロセスがロード済みの共有ライブラリページに自分が初めてマップするとき、中身は page cache にあるので 新しい I/O は要らず、自分の PTE をそのページへ向けるだけ で済みます。CoW による複製も、コピー元はメモリ上にあるためマイナーに分類されます。

メジャーフォルト(major / hard fault) は、必要なデータがメモリに無く ストレージから読み込む ケースです。プロセスは I/O 完了までブロックされるため、待ち時間がマイナーより桁違いに長くなります。つまり アプリの体感速度を決めるのはメジャーフォルトの発生回数 であり、チューニングの主目標になります。/proc/<pid>/statminflt/majfltps -o min_flt,maj_fltvmstat などで両者を計測できます。

ハンドラの分岐:何を埋めるか

正当なフォルトと判定された後、ハンドラは VMA の種類とアクセス内容から 物理ページの中身をどう用意するか を分岐します。

page_fault(addr, error_code):
    vma = find_vma(addr)
    if vma が無い or 許可違反:
        → SIGSEGV(不正アクセス)

    if 書き込みフォルト and PTE が read-only:
        # 共有読み取り専用ページへの書き込み
        → CoWフォルト:ページを複製し、複製先を書込可で繋ぐ(マイナー)

    elif PTE が「スワップ済み」を示す:
        → スワップインI/Oを発行(メジャー)、復帰後にPTEを繋ぐ

    elif 匿名マッピング(ヒープ/スタック/MAP_ANONYMOUS):
        → ゼロ初期化ページを割り当てPTEを繋ぐ(多くはマイナー)

    else:  # ファイルバックドマッピング
        if 該当ページが page cache に在る:
            → そのページに繋ぐ(マイナー)
        else:
            → ファイルから読み込み(メジャー)+ 先読み

要点を順に押さえます。

  • 匿名ページ(anonymous):ヒープやスタック、MAP_ANONYMOUS の初回アクセス。中身の出所が無いので ゼロで初期化 したページを与えます。多くの OS は読み取りの初回フォルトを 共有のゼロページ に読み取り専用で繋ぐ最適化を持ち、書き込みが来て初めて専用ページを割り当てます(これも CoW の一形態でマイナー)。
  • ファイルバックドページ(file-backed):実行ファイルや mmap したファイル。該当オフセットのページが page cache にあればマイナー、無ければファイルからの読み込みでメジャーになります。仕組みは メモリマップトファイル(mmap) を参照。
  • スワップ済みページ:以前 ページ置換アルゴリズム によって追い出されたページ。PTE にスワップの位置が記録されており、スワップインの I/O(メジャー)で復帰させます。

CoW フォルトとの関係

CoW(コピーオンライト)は、ページフォルト機構の上に成り立つ典型例です。fork 直後、親子は同じ物理ページを 読み取り専用 で共有します。どちらかが書き込もうとすると、読み取り専用ページへの書き込みとして ページフォルトが発生 し、ハンドラが「これは権限違反ではなく CoW だ」と判定して そのページだけを複製、書き込み側の PTE を新しいページに書込可で繋ぎ直します。

ここで重要なのは分類です。CoW フォルトはマイナーフォルト です。コピー元のページは必ずメモリ上にあるため、ディスク I/O が発生しないからです。コストはページ複製(memcpy)とページ割り当てであり、メジャーのような I/O 待ちはありません。詳細な動作は コピーオンライト(CoW) を参照してください。

同じ「書き込みフォルト」でも意味が違う

読み取り専用ページへの書き込みフォルトは、文脈で意味が変わります。CoW 用に意図的に read-only にした共有ページなら正当な CoW フォルトとして複製します。一方、本当に書き込み禁止の領域(定数領域や .text など)への書き込みなら権限違反として SIGSEGV です。ハンドラは VMA の本来の許可と PTE の現在状態を突き合わせてこれを見分けます。

先読み(readahead):メジャーフォルトをまとめる

メジャーフォルトは I/O 待ちが重いので、1 回の I/O でまとめて多くのページを取り込む ことが効きます。これが 先読み(readahead) です。フォルトしたページの周辺(後続のオフセット群)を、まだ要求されていなくても投機的に読み込んでおきます。

効く理由は 空間的局所性I/O の固定コスト にあります。ディスク(特に回転体)では、シークなどの固定コストが 1 回の I/O に乗るため、1 ページずつ N 回読むより連続した N ページを 1 回で読むほうが圧倒的に速い。先読みが当たれば、後続ページは到達時点で page cache に居るので メジャーが起きずマイナーで済む、あるいはフォルトすら起きません。

逐次アクセス時の効果:
  先読みなし:  fault→read(1) … fault→read(1) … fault→read(1)   ← 毎回I/O待ち
  先読みあり:  fault→read(N) ………………………                ← 1回のI/Oで後続Nページを充填
               以降は cache ヒット(メジャーが消える)

カーネルはアクセスパターンを観測して 先読みの量を適応的に調整 します。逐次アクセスを検知すると先読み窓(read-ahead window)を広げ、ヒットが続く限り拡大します。逆にランダムアクセスを検知すると先読みを縮小・停止します。無駄な先読みは page cache を汚し、本当に要るページを追い出して逆効果になるためです。madviseMADV_SEQUENTIAL/MADV_RANDOM/MADV_WILLNEED でアプリ側からヒントを与え、この挙動を制御できます。

試験・面接で問われる勘どころ

(1)マイナー=I/Oなし、メジャー=I/Oあり、という定義の軸を即答できること。(2)CoW フォルトがマイナーである理由(コピー元がメモリ上にある)。(3)デマンドページングが RSS を確保量より小さく保つ理屈。(4)readahead が効くのは逐次アクセス+I/O固定コストが理由で、ランダムでは逆効果になりうること。この 4 点が頻出です。

まとめ

  • デマンドページング は、確保時には PTE を無効のままにし、初回アクセスのページフォルトで初めて物理ページを埋める 遅延戦略。起動を速くし、確保量に対して RSS を小さく保つ。
  • ハンドラはまず VMA 照合で正当性を判定 し、不正なら SIGSEGV。正当なフォルトは 匿名・ファイル・スワップ・CoW に分岐して中身を用意する。
  • フォルトは マイナー(I/Oなし)メジャー(I/Oあり) に分かれ、体感性能を支配するのはメジャーの回数。CoW フォルトはコピー元がメモリ上にあるためマイナー
  • 先読み(readahead) は周辺ページを投機的に読み、メジャーをまとめて減らす。逐次では有効、ランダムでは逆効果になりうるため適応制御される。

前提は 仮想記憶のアドレス変換とMMU/TLBの内部メモリマップトファイル(mmap)、追い出し側の論理は ページ置換アルゴリズム、書き込み時複製は コピーオンライト(CoW) も合わせて読むと全体像が繋がります。

OS Article

デマンドページングとページフォルト処理を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

デマンドページング

比較で見る軸

難易度: advanced / カテゴリ: OS / タグ数: 6

導入後に効く点

フォルトは、I/Oを伴わず既存ページに繋ぐだけのマイナーフォルトと、ディスクからの読み込みが要るメジャーフォルトに分かれる。性能を支配するのは後者の回数。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
OS
タグ数
6

判断チェックリスト

  • 自社の用途が「デマンドページング / ページフォルト」に近いか確認する。
  • 強みである「デマンドページングは、メモリ確保時には物理ページを割り当てず、最初にアクセスされた瞬間のページフォルトで初めて中身を埋める遅延戦略。起動とメモリ使用量を抑える。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

デマンドページングページフォルト仮想記憶readaheadメモリ管理デマンドページングページフォルト仮想記憶
参考: 公式情報