仮想記憶
まず、以下の議論の前提とする、簡略化した典型的な記憶装置の階層構造のモデルを述べる。
CPU内のレジスタ。CPUのクロック速度で動作するため、最も高速である。レジスタの使用は一般に呼出規約の制限下にあり、コンパイラによる管理に任せられる。大きな容量はないため(32ビットあるいは64ビット、現代的なマイクロプロセッサでは16本〜普通は100本前後)次の計算が使えるように明け渡す必要があり、データを長期間保持させることは通常はできない。内部的にはレジスタ・リネーミングを行っていることもある。
CPU内かCPUに隣接したキャッシュメモリ。通常はある種のSRAMを使用。レジスタに次いで高速であるが、容量は128kバイト〜数メガバイト程度に留まる。近年では1次キャッシュから3次キャッシュまでもがオンダイという場合もあり、ここで示した容量などに特に拘る意味は無い。
主記憶装置(通常はDRAMを使用)は、プログラミング上CPUが直接リード/ライトできる。キャッシュメモリに比べると速度は落ちるものの、より大きな容量(数百メガバイト〜数ギガバイト)を装着できる。
補助記憶装置としての磁気ディスク装置は、機械的な動作を伴うため、主記憶装置と比べても桁違いに低速だが、数十ギガバイト~数十テラバイト以上と容量が大きい。
主記憶装置とキャッシュメモリのどちらを使用するかは、一般にハードウェアに任せられているため、プログラマからはどちらも同じ物理メモリとしてしか見えない(しかし性能への影響は大きいので、高性能計算など、キャッシュヒット率を考慮してコードを書くこともある)。
ページングファイルのサイズには初期サイズと最大サイズがあり、ページングファイルが不足するとページングファイルは最大サイズまで拡張される。徐々に拡張された場合、フラグメンテーションが起き、性能に悪影響を与えることがある。これに対する助言としては、ページファイルのサイズを固定することでOSがそのサイズを変更できないようにするという対策がある。ただし、ページファイルが拡張されるのは全部を使い切ったときで、デフォルト設定では物理メモリの150%の量になっている。したがって、ページファイルに対応した仮想記憶の要求が物理メモリの250%を越えないと、ページファイルは拡張されない。
ページファイルの拡張によるフラグメンテーションは一時的なものである。拡張された領域が使われなくなれば(遅くとも次回の再起動時には)、追加で確保されたディスク領域は解放され、ページファイルは本来の状態に戻る。
ページファイルの大きさを固定にすると、物理メモリとページファイルを合わせた以上のメモリを要求するアプリケーションがある場合に問題となる。その場合、メモリ確保要求が失敗し、アプリケーションやシステムプロセスが異常終了する可能性がある。
これは、mmapやWin32のMapViewOfFileのような機構とは異なる。mmap等ではファイルは任意の位置にマッピングされる可能性があるため、ファイル間のポインタは使えないためである。Multicsでは、ファイル(複セグメントファイルの場合はセグメント)はセグメント機構を通してアドレス空間にマッピングされる。そのためファイルは常にセグメント境界にマッピングされる。ファイルのリンク部分にはポインタが並んでおり、そのポインタをレジスタにロードしたり間接参照したりするとトラップが発生する。未解決のポインタにはセグメント名を示す値とセグメント内オフセットがある。トラップハンドラは対応するセグメントをアドレス空間にマッピングし、ポインタのセグメント識別子部分をセグメント番号に書き換えるので、2度目以降はそのポインタにアクセスしてもトラップが発生しなくなる。この方式ではリンケージエディタが不要であり、同じファイルを複数のプロセスが異なる位置にマッピングしても問題なく機能する。
テキストセグメントはファイルシステム上の実行ファイルの一部と完全に対応しており、書き換えられることもない。従って、マッピングしているオブジェクトは実行ファイルであり、アクセス属性は「リードオンリー」となる。データセグメントやスタックは一時的な存在であるため何かをマッピングしているわけではない。そこでこれらは匿名ファイル(Anonymous File)をマッピングしているものとして管理される。匿名ファイルをマッピングしているセグメントに対応するページを匿名ページと呼び、これがスワッピングの際にスワップ領域に書き出される。データセグメントは当初は実行ファイルの一部と対応しているが、書き込み可能な属性が設定されている。ページング方式の場合、データセグメント内の内容が更新されたページはページ単位で匿名ページへと属性変更される。
exec() システムコールなどで新たにプロセスの仮想アドレス空間を設定した当初は、基本的にこのような仮想アドレス空間を管理するデータ構造がカーネル内に作成されるだけで、実際の実行ファイルの内容はロードされない。Unix系システムでは、exec() システムコールからユーザ空間に制御が戻された瞬間にページフォールトが発生し、そこで初めてページ単位に実行ファイルの内容がロードされる。ただし、性能向上目的で事前にマッピングを作成する場合もある。
各プロセスの仮想アドレス空間のアドレス範囲は同じでありオーバーラップしているのが一般的である。