仮想記憶
なお、アーキテクチャによっては、多重仮想記憶がオーバーラップしていると捉えず、全仮想空間がフラットに並んだ巨大な仮想空間を想定することもある。この場合、仮想空間識別番号が巨大な仮想空間のアドレスの一部と考えられる。もっとも、これは単にモデル化の手法が違うだけで実装に大きな違いがあるわけではない。実際、各ユーザープロセスが自分の仮想空間識別番号以外の仮想空間にアクセスすることはできない。
1962年に世界で初めてページングをサポートしたコンピュータAtlasは、フェランティ、マンチェスター大学、Plesseyが共同開発した。このマシンには連想メモリがあり、1エントリに512ワード長のページが対応している。スーパーバイザは非同値割り込みを処理し「非同値割り込み」は、アドレスの上位ビット列(ページ番号)が連想メモリのどのエントリとも一致しないとき発生する。、磁気コアメモリと磁気ドラムメモリ間のページ転送を管理する。特筆すべきは、世界初の仮想記憶システムであるにもかかわらず、難しさなどから後のシステムでも実現例のあまり多くない、プログラムに単一レベル記憶を提供していることである。
Windows では、1990年のWindows 3.0から仮想記憶をサポートしている。マイクロソフトはWindows 1.0とWindows 2.0での失敗を受け、OSへのリソース要求を削減するために仮想記憶を導入した。
全てのプロセスは固定の変更不可能な仮想記憶空間を持っている(32ビットの場合、一般に2GB)。
Windows 3.xには隠しファイルとして<tt>386SPART.PAR</tt>または<tt>WIN386.SWP</tt>があり、それらがスワップファイルとして使われる。通常、ルートディレクトリにあるが、WINDOWSなど他のディレクトリに置くこともある。そのサイズはコントロールパネルで設定される「仮想メモリ」サイズで決定される。ユーザーがこのファイルを削除したり移動させたりすると、次回Windowsを起動したときにブルースクリーンが表示され、エラーメッセージが表示される(英語では "The permanent swap file is corrupt")。
Windows 95、Windows 98 / 98 SE、Windows Me でも同様の仕組みになっている。スワップファイルの大きさはデフォルトでは物理メモリ量の1.5倍であり、最大で物理メモリの3倍まで拡張できる。
NT系のWindows(Windows NT、Windows 2000、Windows XP、Windows Vista、Windows 7、Windows 8 / 8.1、Windows 10およびWindows Serverシリーズなど)は、<tt>pagefile.sys</tt>というファイルを使用する。このファイルのデフォルトの位置はWindowsをインストールしたパーティションのルートディレクトリである。Windowsは任意のドライブの空き領域をページファイルとして使用できる。XPまでのWindowsではシステムクラッシュ時にカーネルまたは全メモリをダンプする設定にしている場合、ブートパーティション(Windowsがインストールされたドライブ)にこのファイルを置く必要があった(ダンプ先として使用するため)。リブートすると、システムがダンプを通常のファイルに移す。
ページングファイルのサイズには初期サイズと最大サイズがあり、ページングファイルが不足するとページングファイルは最大サイズまで拡張される。拡張されたページングファイルは再起動するまで小さくならない。サイズ設定値が小さい場合、動作が不安定になるアプリケーションもある。
ページングファイルがあると、積極的なクリーニングにより物理メモリで足りる場合であってもページファイルへの書き出しが行われる。積極的なクリーニングは仮想記憶を実装するページ置換アルゴリズムの一つで、CPUの余剰時間を使ってページ内容をディスクに書き出しクリーンな状態にしておき、ページが必要になった時に短時間でページを再利用する手法である。勿論クリーンな状態のページ内容そのものが必要になった時には、ページファイル上のページ内容を無視するだけで良いので、オーバーヘッドは発生しない。
Windows XP以降ではページファイルを使用しないオプションが選択できる。もちろんこれは物理メモリの容量が十分に足りている場合(かつ、ページファイル必須アプリケーション運用を必要としない場合)にのみ選択すべきオプションである。ページファイルを使用しない場合、ほとんど使用されない常駐ソフトなどのデータをスワップアウトすることができなくなるので、キャッシュとして使える物理メモリの空き領域が減ってパフォーマンスが低下することがある。いくつかのアプリケーションが動作しなくなったり、システム機能が効率的に動作しなくなったり、といったことも発生しうる。しかし、ファイルを読み書きするI/Oアクセスが起こらないため、パフォーマンスを落とさないというメリットがある。
32ビット版Windowsでは、バージョンおよびエディションにも左右されるが、ページングファイルのサイズは最大36ビットのアドレス空間すなわち64GiBまでサポートされる。
ページングファイルのサイズには初期サイズと最大サイズがあり、ページングファイルが不足するとページングファイルは最大サイズまで拡張される。徐々に拡張された場合、フラグメンテーションが起き、性能に悪影響を与えることがある。これに対する助言としては、ページファイルのサイズを固定することでOSがそのサイズを変更できないようにするという対策がある。ただし、ページファイルが拡張されるのは全部を使い切ったときで、デフォルト設定では物理メモリの150%の量になっている。したがって、ページファイルに対応した仮想記憶の要求が物理メモリの250%を越えないと、ページファイルは拡張されない。
ページファイルの拡張によるフラグメンテーションは一時的なものである。拡張された領域が使われなくなれば(遅くとも次回の再起動時には)、追加で確保されたディスク領域は解放され、ページファイルは本来の状態に戻る。
ページファイルの大きさを固定にすると、物理メモリとページファイルを合わせた以上のメモリを要求するアプリケーションがある場合に問題となる。その場合、メモリ確保要求が失敗し、アプリケーションやシステムプロセスが異常終了する可能性がある。ページファイルを拡張可能にすべきだという根拠として、ページファイルが先頭から順にシーケンシャルにアクセスされることはなく、ページファイルが連続領域になっていること性能上の利点はほとんどないという見方もある。いずれにしても、メモリを大量に使うアプリケーションを使用するならページファイルは大きい方がよく、ページファイルを大きくしてもディスク容量がそれに割かれる以外のペナルティはない。
現代的な仕様のシステムでは余分にディスク領域を使用しても問題はない。例えば、メモリが3GBのシステムで6GBの固定スワップファイルを使用するとしても、HDDが750GBなら問題はないし、メモリが6GB、スワップファイルが16GB、HDDが2TBなら、これも問題はない。どちらの場合もスワップファイルとして使用する領域はHDDの1%に満たない。
ページファイルは任意のドライブに作成する事ができる。これはUNIX同様スワップ専用のパーティション割り当てが行えるのに等しい。またページファイルはストライピングが行われるので複数のハードディスクドライブに小分けにしてページファイルを作成すると、ページング速度が向上する。
物理メモリ以上のメモリを常に使うような使い方をする場合、ページファイルのデフラグメンテーションをすることで性能が改善する可能性もある。しかし、根本的には物理メモリを追加する方が性能改善に役立つ。
Mac OSはSystem 7から「仮想メモリ」として実装される。当時はコントロールパネルでメモリサイズ(メインメモリのサイズを加算した値)を指定し機能を入にすることで使用できるようになる。すると起動ディスクに隠しファイルとしてスワップファイルが作成される。スワップファイルは指定したメモリサイズの大きさとなり、これ以上は増えない。この頃の仮想メモリは使用しているかどうかでプログラムの動作が不安定になることがあった。そのため、プログラムのパッケージや説明書には仮想メモリの設定を確認させる記述が見られる。
UNIXおよびUnix系OSでは、ハードディスクのパーティションを丸ごとスワップに使用することが多く、そのようなパーティションをスワップパーティションと呼ぶ。ドライブを1個丸ごとスワップパーティションとすることもある。そのようなドライブをスワップドライブなどと呼ぶ。スワップパーティションしかサポートしないシステムもあるが、ファイルへのスワッピングもサポートするシステムもある。フラグメンテーション問題を回避して性能を維持するためにもパーティションの使用が推奨されている。また、スワップパーティションを使うと、スワップ領域をディスク内の最も高速アクセス可能な場所に配置できる。最近のハードディスクでは、先頭の方がよいとされている。
Linuxのユーザプロセスから見れば、大局的にはメモリはCPUキャッシュ (L1, L2, …)、メインメモリ、ファイルの順に階層化されており、上位(CPUにより近い)メモリは下位メモリのキャッシュに過ぎない。実行可能なファイルや共有ライブラリのテキストセグメントやmmapで明示的にマップされる名前付きファイルに対して、スワップエリアはスタックやヒープを保持する名無しファイルである(データセグメントやBSSセグメントは読み出し専用の実行可能ファイルや共有ライブラリファイルからプロセス固有の読み書き可能な無名ファイルに展開・コピーされると考えられる)。もちろん、実際にはカーネルは性能維持のためにスワップエリアの使用とアクセスを最小限にするような最適化の努力を払う(メインメモリに余裕があればスワップエリアには書き出さず「キャッシュ(メインメモリ)」だけにしか情報が保持されない)。
2.6のLinuxカーネルではスワップファイルはスワップパーティションと同程度の性能である。カーネルはスワップファイルの存在するディスク上の位置を把握しており、バッファキャッシュやファイルシステムのオーバヘッドを回避して直接ディスクにアクセスする。レッドハットはスワップパーティションの使用を推奨している。スワップパーティションの場合、ディスク上の位置を決めることができるので、スループットが最も高い場所に置くことができる。一方スワップファイルは管理の柔軟性という点でスワップパーティションに優っている。例えば、スワップファイルは任意のドライブ上に置くことができ、どんな大きさにもでき、必要に応じた追加や変更が容易であるだけでなく、ネットワークを介して外部ホスト上のリモートファイルを使うことも可能である。一方、スワップパーティションは一度位置と大きさを決めたら、ドライブ全体のパーティショニングをやり直さないと変更できない。
Linuxは事実上無制限な個数のスワップデバイスをサポートし、それぞれに優先度を設定できる。オペレーティングシステムが物理メモリをスワップアウトする場合、最高優先度のデバイスの空き領域から使っていく。同じ優先度に複数のデバイスがある場合、それらは RAID 0と同様の使い方をされる。これによって並列的に複数のデバイスにアクセスするので性能が向上する。従って優先度の設定には注意が必要である。例えば、同じドライブ上の複数のスワップ領域を同じ優先度にするのは得策ではない。また、高速なデバイスを高優先度に設定するのが性能的に有利である。
Linuxシステムでスワップを追加するには、その前にスワップ領域を作成しなければならない。パーティションならば一般のパーティション作成ツールが使用できる。通常ファイルの場合、<tt>dd</tt>コマンドと <tt>/dev/zero</tt>を使って内容がゼロのファイルを作ることができる。作成したスワップ領域は<tt>mkswap</tt> filename/deviceでフォーマットし、<tt>swapon</tt>および<tt>swapoff</tt>コマンドでON/OFFを制御する。
Windowsとは違い、物理メモリに入りきらない場合のみ、スワップが利用される。これは積極的なクリーニングが実装されていないためで、ページングが開始された時システムは著しい速度低下を起こす(スラッシング)。しかし、これは物理メモリが飽和状態を続けている場合さほど深刻では無い。メモリが飽和すればあまり利用されないページは自ずとハードディスクに追い出され、物理メモリには有用なページが残される様になる。
macOSではUnix系をベースとしたことで仮想メモリは常に使用するようになっており、複数のスワップファイルを使用できる。デフォルト(かつアップルの推奨)ではルートパーティションに配置されるが、他のパーティションやデバイスに置くこともできる。
コンピュータの起動時から64MBのスワップファイルが1つ作成されている。場所は/private/var/vm/以下で、swapfilenという名前がつけられている(nは0からの数字)。容量が不足するとスワップファイルは自動的に追加される。swapfile1までは64MB、以降のスワップファイルのサイズは128MB、256MB...と8の倍数で増えるのが基本だが、メモリの最大容量・ハードディスクの空き容量の1/4・1GBのいずれか小さい方を選択し容量が決定する。ひとつのスワップファイルが大きくなるのではなく複数のファイルが作成される。すなわちスワップファイルが4つなら64+64+128+256で合計512MBとなる。スワップファイルの場所はコマンドライン操作などで他のデバイスに変更できる。
スワップファイルを削除するアプリケーションも存在し、これを用いなくとも削除できる(ただし、削除後は再起動するのが望ましい)。また、一旦ログアウトしてからログインしなおすと再起動することなく削除できる。
macOSでは多重仮想記憶がサポートされ、仮想空間はプロセス毎に資源が分離されている。この違いが、Classic Mac OSとmacOSでの仮想記憶に対する信頼性の違いとなって現れている。