はじめに
4章で最も重要な概念の一つである仮想記憶を中心に要点をメモしていきます。この仮想記憶のおかげで、仮想アドレス空間上で実行されるコンピュータのプログラムが、実際のデータの格納場所である物理メモリの物理アドレスにマッピングされます。
仮想記憶がない時の問題
仮想記憶がない場合、コンピュータの物理メモリに物理アドレスを使用して直接アクセスすることになります。それにより、以下のような問題が発生します。
① メモリの断片化(メモリフラグメンテーション)
プロセスの生成と終了により、メモリの確保と解放を繰り返すことで、バラバラの位置にメモリの空き領域ができてしまう、メモリの断片化という問題が発生します。例えば、連続していない3つの領域に100バイトずつ空きが存在する場合を考えます。この時、メモリをかき集めれば合計300バイトも空いているのに、100バイトの領域がまばらに存在するため、100バイトより大きなデータの格納ができなくなります。この場合、連続したメモリ領域を必要とする200バイトの配列を格納できなくなってしまいます。
② マルチプロセスの実現が困難
仮想記憶を使用しない場合、プロセスAとプロセスBのアドレスが重複する(同じ領域にマップされる)ことで、または別の領域にマップされることで問題が発生し、正しく動作しなくなります。
③ 不正な領域へのアクセスが可能
あるプロセスがメモリ上に配置されている別のプロセスやカーネルのメモリアドレスを指定することで、それらの領域に自由にアクセスできてしまうため、データが壊れてしまう可能性があります。
仮想記憶の特徴
仮想記憶の機能を使用することで、これらの問題を解決することができます。仮想記憶により、プログラムがメモリアクセスする際に物理メモリに直接アクセスするのではなく、仮想アドレスを使用して間接的に物理メモリにアクセスすることができます。具体的な流れは以下になります。
- プロセスが仮想メモリにアクセス
- MMUというCPUのハードウェアにより仮想メモリが物理メモリに変換される
ページテーブル
このようなアドレスの変換を行う際に「ページテーブル」という、仮想アドレスと物理アドレスの対応表が使用されます。ページテーブルは、物理メモリ内に存在するカーネルのメモリに保存されます。プロセスごとにページテーブルが作成され、CPUはページ(仮想メモリを一定のサイズに分割したブロック)という単位ごとに、アドレスの管理を行います。
ページフォールトとページフォールトハンドラ
プロセスが対応する物理アドレスを持っていない仮想アドレス(ページ)にアクセスした際には、ページフォールトという例外が発生します。この例外により、CPUで実行中のプログラムが停止され、ページフォールトハンドラ(カーネルのメモリに存在)という処理が実行されます。これ以降の処理は以下の2つの場合に応じて分岐されます。
① ページに対応する物理メモリが存在しない場合
ページテーブルエントリに対応する物理アドレスが存在しないと示されている場合、ページフォールトハンドラはプロセスが不正なメモリアクセスを行なっていることを検出すると、当該プロセスに対してSIGSEGVというシグナルを送信し、SIGSEGVを受信したプロセスは強制終了します。
② 対応する物理アドレスが未割り当ての場合
ページテーブルエントリに対応する物理アドレスが存在するが未割り当てと示されている場合、ページフォールトハンドラは物理メモリの割り当てを新たに行います。物理メモリの割り当てには、デマンドページングという仕組みが使用されます。
プロセスへの新規メモリ割り当て
新規のメモリ割り当てのステップは以下の2つのステップに分かれます。
① 新規メモリ領域の割り当て
mmap()システムコールを呼び出し、仮想アドレス空間に新たに使用可能なメモリ領域を割り当てます。しかし、この段階では新規に獲得した仮想アドレス領域に対応する物理アドレスの紐付けは完了していません。
② メモリの割り当て
デマンドページングにより、上のメモリ領域に物理アドレスを割り当てます。デマンドページングとは、新たに獲得した領域の各ページに最初にアクセスした時に、物理メモリの割り当てを行う仕組みです。
仮想記憶による問題①~③の解決
仮想記憶を使用することで、「仮想記憶がない時の問題の問題」で示したような問題を解決することができます。
①メモリの断片化
仮想記憶とページテーブルを使用することで、不連続な物理メモリ領域であっても、連続したメモリ空間として扱うことが可能となり、断片化の問題が解決できます。
② マルチプロセスの実現が困難
仮想アドレス空間はプロセスごとに作成されるため、他のプロセスとの物理アドレスの重複を避けることができます。
③ 不正な領域へのアクセス
仮想アドレス空間がプロセスごとに作成されるということは、他のプロセスのメモリにアクセスすることは不可能なので、不正な領域へのアクセス問題も解決することができます。