Skip to content

MS_VirtualMemoryManagement

nishi_74322014 edited this page Aug 3, 2026 · 1 revision

仮想メモリ管理

概要

仮想アドレス空間にマッピングされた各コミット済みページは

  • 物理メモリ
  • 物理ストレージ(ページングファイル、メモリマップトファイル)

に支持(バック)される。

ページ

  • Windows のユーザープロセスに対する仮想アドレス空間は、3 種類のページに分類できる。
    • リザーブ(予約済み)
    • コミット
    • ワーキングセット
  • 仮想メモリの各フラグメント(断片)をページといい、サイズは通常 4KB である。

予約済みページ

  • VirtualAlloc で予約したページ
  • 将来の使用に備えて予約されたページ。
  • 予約済みページは、物理ストレージや、物理メモリを占有しない。
  • しかし、仮想アドレス空間が予約されるため当該プロセスのみのメモリ・リーク、
    正確には、当該プロセスの仮想アドレス空間のリークが発生することはある。

コミット済みページ

  • プロセスのコミット済みページ
  • アプリケーションがコミット済みページにアクセスすると、
    オペレーティングシステムはそのページをワーキング セットに指定する。

ワーキングセット

仮想アドレスに直接関係しないプロセスの所有する物理メモリ
(詳細は物理メモリ管理)。

移行メモ: 厳密には「リザーブ / コミット / ワーキングセット」は 同じ軸の3分類ではない。 リザーブとコミットは仮想アドレス空間の状態、 ワーキングセットは物理メモリ側の概念である。 「予約 → コミット → (アクセスされて)物理メモリに常駐=ワーキングセット」 という流れを一続きに説明したものと解される。

32ビットと64ビット

32bitの仮想アドレス空間 64bitの仮想アドレス空間
合計 4GB 合計 16TB
2GB がカーネルモード 8TB がカーネルモード
2GB がユーザモード 8TB がユーザモード

補足(最新化): 16TB(各 8TB)は Windows 8.1 / Server 2012 R2 までの値。 Windows 8.1 以降は 256TB(ユーザ 128TB / カーネル 128TB)に拡張されている (4レベル ページ テーブル、48bit のアドレス)。 さらに Windows Server 2022 以降は 5レベル ページ テーブル対応により 最大 128PB まで拡張されうる。

32bit

仮想アドレス空間

32bit のデフォルトで

  • ユーザモード(0x000000000x7fffffff
  • カーネルモード(0x800000000xffffffff

AWE

AWE により、32bit プロセスでも扱える物理メモリを拡張可能
(APP が AWE をサポートしていれば AWE の API を使用して独自にメモリ管理をする)。

また、3GB スイッチでユーザモードを x86:3GB、x64:4GB※ に拡張可能。
※ 32ビットプロセス(WOW64)でアクセス可能な仮想アドレス空間にカーネル空間が
存在しないため、4GB をフルに活用できる。

移行メモ: 原文は AWE を「仮想アドレス空間の拡張」としていたが、 AWE(Address Windowing Extensions)は 仮想アドレス空間を拡張するものではない。 2GB の仮想アドレス空間に「窓」を開け、そこへ 2GB を超える物理メモリを 付け替えながらアクセスする仕組み。 したがって拡張されるのは「使える物理メモリ量」である。

なお 3GB スイッチ側は、実行イメージに IMAGE_FILE_LARGE_ADDRESS_AWARE が立っている必要がある。 いずれも 32bit OS 固有の延命策で、64bit 化すれば不要。

仮想アドレス空間

カーネルモード・ユーザモードの仮想アドレス空間

カーネルモード

カーネルモードの仮想アドレス空間は、全てのプロセスで共有される。

  • スレッドの開始アドレスが 0x80000000(デフォルト)より上位にある場合、
    そのスレッドはカーネルモード・スレッドになる。
  • カーネルモード・スレッドを作成したデバイス・ドライバを特定するためには、
    スレッドの開始アドレスを調べ、そのアドレスの上位で最も近いベースアドレスを持つドライバを探す。

※ これらの調査の操作は、Process Explorer に統合されている(★)。

以下のツールも利用可能。

  • Dependency Walker を使用すると、
    プロセスで利用されている .sys(ドライバ)を確認できる。

関連

メモリ プール

メモリ プール(ページ プールおよび非ページ プール)

ページ プール

ページング可能なメモリ プール
(レジストリやメモリ マップ ファイルを表すデータ構造が格納される)

非ページ プール

ページング不可能なメモリ プール
(カーネルとデバイス ドライバーが、システムがページ フォールトを処理できないときに
アクセスされる可能性があるデータを格納している)

カーネル モードで動作するモジュール(ドライバ)から確保され、
モジュール(ドライバ)を識別可能なタグ名が付与される。以下の API により確保される。

PVOID ExAllocatePoolWithTag(
  IN POOL_TYPE PoolType,
  IN SIZE_T    NumberOfBytes,
  IN ULONG     Tag              // <<<<<
);

このタグを利用してリークの原因となっているモジュールを特定できる。

※ タグごとのプール使用量は poolmon.exe(WDK 付属)で確認できる。
非ページ プールが増え続ける場合、ドライバ起因のリークを疑う
メモリ・リークを参照)。

補足(最新化): ExAllocatePoolWithTag は Windows 10 2004 以降 非推奨となり、ExAllocatePool2 / ExAllocatePool3 が推奨されている (既定でゼロ初期化される点が異なる)。

参考


Tags: Windows, メモリ管理, 障害対応, 性能, デバッグ

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally