MMU とは?
MMU の正式名称は、「Memory Management Unit」といい、「メモリ管理ユニット」と訳します。
「物理アドレス」と「論理アドレス」を相互に変換できるようにする仕組みで、
主にOS(Operating System)が責務を担う機能です。
Windows を始め、Linux、FreeBSD など、現代の OS には
必ずと言っていいほど MMU の機能が備わっています。
本記事では、MMU の基本的な仕組みから、なぜ必要なのか、どんなメリットがあるのかまで、
図を交えながらわかりやすく解説します。
基本用語の説明
MMU
メモリ管理ユニット(Memory Management Unit)の略です。
現代のコンピュータ、スマートフォンなどには不可欠な仕組みです。
物理アドレス
物理アドレスとは、メモリのハードウェア上の番地です。
物理的なモノ(メモリ)のアドレスを指すため、物理アドレスと言います。
論理アドレス/仮想アドレス
実際に物理的なモノとして存在しないアドレスで、
アプリやプログラム上でのみ意味を持つ架空のアドレスのことです。

なぜ MMU が OS に必要なのか
「マルチプロセス」または「マルチタスク」という言葉を聞いたことはないでしょうか。
実は、複数のプログラムが同時に動く仕組みである「マルチプロセス」や「マルチタスク」を
実現するためには、MMU の機能が必須となります。
例えば、プログラムAとプログラムBが同時に実行されている(マルチプロセス)場合を考えます。
同時に実行する場合、メモリ上に次のような情報が記憶されている必要があります。
- プログラムA のバイナリ(プログラム自体)
- プログラムA が使用するスタック(オート変数とか関数呼出スタックの保存、等)
- プログラムA が使用する一時的な保存領域(ファイルの中身を読込むバッファ、等)
- プログラムB のバイナリ
- プログラムB が使用するスタック
- プログラムB が使用する一時的な保存領域
MMU が無い場合どうなる?
簡単にするため、メモリが 64K バイトの場合で考えてみましょう。
物理アドレスは 0000H 番地から FFFFH 番地になります。

プログラムA と プログラムB の両方を同時に動かすとき、先ほど挙げた全情報が同時期に、
メモリ上に配置・存在している必要があります。例えば、
- プログラムA は、0100H 番地から配置する
- プログラムB は、1100H 番地から配置する
という具合に、それぞれのプログラムが重ならないように配置すれば、問題ないようにも見えます。

プログラムA と プログラムB の配置
しかし、この方法には以下のような問題が生じます。
問題点
- プログラムそのものに埋め込まれているアドレスはどう扱うのか
- プログラムの起動/終了を繰り返しているうちに虫食いになる

問題点:プログラムそのものに埋め込まれているアドレスの扱い
例えば、以下のような命令が プログラムB に組み込まれている場合を想定します。
1 2 3 4 |
(snip) mov [110], ax (snip) |
この mov 命令に続く 110 は、メモリの 110H 番地を表しており、
ax という汎用レジスタから 110H 番地に値を保存するという動作をします。
もし、この命令が実行されると、プログラムB が プログラムA の領域に値を書き込んでしまうことになり、
プログラムA の動作が破綻してしまいます。




書込む番地は 1110H になるので問題は起きなくなります。


処理速度(性能)が極端に悪くなるという別の問題が発生します。
問題点:プログラムの起動/終了を繰り返しているうちに虫食いになる
例えば、以下のような流れを考えてみましょう。
簡単な流れ
- プログラムA の実行が終了し、使用していたメモリが不要になった
- プログラムA が占有していた領域が、未使用の空き状態になる
- 新たに プログラムC を実行する
新たに実行する プログラムC が プログラムA のサイズと 全く同じか小さいなら、
プログラムA が占有していた領域に読み込めばいいだけだで事なきを得るでしょう。
しかし、異なるプログラムが全く同じサイズになることは有り得ません。
そのため、プログラムC は他のメモリ領域に読み込まねばならず、
かつて プログラムA が占有していた領域は空いたままとなります。

プログラムBと プログラムC の配置
複数のプログラムを読込んだり終了させる動作を繰り返していくと、
このようなメモリ内の虫食い穴(フラグメント)が増えていきます。
その結果、実際に利用できるメモリの量が、どんどん減少していく可能性があります。
そこで登場したのが MMU の仕組み
仕組みの概要
先ずは、簡単な仕組みから見ていきましょう。
MMU は先の問題を解決するため、「論理アドレス」の考え方を取り入れて、
「物理アドレス」と「論理アドレス」を相互にアドレス変換を行う仕組みです。
アドレス変換を行うための表をページテーブルと言い、
TLB (Translation Lookaside Buffer) というバッファに保存して参照します。
仕組みの詳細
先ほどと同様に、メモリが 64K バイトの場合で考えてみましょう。
64K バイトのアドレスは 16bit(2^16乗 = 64K)で表現され、
それぞれのビットを信号で伝えるアドレスバスがメモリに接続されます。
アドレス変換の流れ
- 例えば、論理アドレス 1100H 番地を上位 8bit(ページ番号)と下位 8bit(オフセット)に分離
- 論理ページ番号 11H と一致する物理ページアドレスの上位 8bit を、TLB を参照して変換
- 下位 8bit は変換せずにそのまま使用
- すると、論理アドレス 1100H 番地を物理アドレス 3300H 番地に変換できる
この例の場合、オフセットを示す下位 8bit の 1 バイト単位を「ページ」と呼び、
ページ単位で管理することを「ページング」と言います。

ポイント
メモリ管理ユニット(MMU)とは、ページテーブル(TBL)を使って変換テーブルを保持し、
「物理アドレス」と「論理アドレス」を相互に変換する仕組み。
MMU を搭載するメリット
MMU を使うと、メモリに関する問題を解決できるだけでなく、以下のメリットもあります。
メリット
- 扱えるメモリ容量が増える
- メモリ破壊を抑止できる (メモリバリア)
扱えるメモリ容量が増える
例えば、先ほどの同様に、メモリが 64K バイトの場合、
すなわち CPU が持っているアドレスバスが 16 本の場合を考えましょう。
上位 4 本のアドレスバスに 16 バイトのメモリを接続し、
そのメモリの 8 本のアドレスバスをメモリに繋いでみます。
上位 4bit の線を接続するため、その線だけで指定できるアドレスは 0H~FH 番地までの16バイトですね。
また、16 バイトのメモリの出力をアドレスの代わりとして使うイメージです。
こうすることで、CPU が扱えるメモリアドレスは
下位 12bit と合わせて 20bit のメモリアドレスに拡張することができます。
つまり、16bit のメモリアドレスのままなら 64K バイトしか扱えないところ、
この方法なら 1M バイトのメモリまで扱うことができるようになります。
メモリ破壊を抑止できる (メモリバリア)
アドレス変換を行うことで、メモリ破壊を抑止することができます。
例えば、プログラムA がアクセスする論理アドレス 0100H 番地と、
プログラムB がアクセスする論理アドレス 0100H 番地は、
実際には異なる物理アドレスを指します。
言い換えると、プログラムA がアクセスする物理アドレスは、
プログラムB には分かりませんし、OSを除くその他すべてのプログラムで知る術が皆無。
プログラムA が暴走して変な論理アドレスにアクセスしても、
アドレス変換エラーが発生したり変な物理アドレスに変換されるため、
他のプログラムが使用しているメモリ領域に危害を加えることが無くなるということです。
また、変換後の物理アドレスへのアクセス権を OS から与えられていなければ、
暴走したプログラムを OS が強制終了させることもできます。

Linux 系では「SIGSEGV」や「SIGBUS」によってプログラムが強制終了します。
MMU と仮想記憶
最後に、先ほど MMU を利用するメリットとして紹介した「扱えるメモリ容量が増える」に関連する
「仮想記憶」の技術についてご紹介いたします。
仮想記憶とは?
仮想記憶とは、物理メモリと補助記憶装置(SSD/HDDなど)を組み合わせて、
実際の物理メモリ以上の容量があるように見せかける技術です。

仮想記憶の動作の流れ
アクセス速度は物理メモリの方が圧倒的に速いため、物理メモリが優先的に使用されます。
メモリがいっぱいになった場合、以下のような流れでデータの入れ替えを行います。
- プログラムは「論理アドレス」を使用してメモリにアクセス
- MMU が「論理アドレス」を「物理アドレス」に変換
- 必要なデータが「物理アドレス」に無い場合(ページフォールト)
- OS が補助記憶装置から必要なデータを「物理メモリ」に読み込む
- 物理メモリが不足している場合は、使用頻度の低いデータを補助記憶装置に退避
おわりに
いかがでしたでしょうか。
MMU は現代のコンピュータシステムにおいて、メモリ管理の要となる重要な仕組みです。
アドレス変換による効率的なメモリ利用や、プログラム間のメモリ保護など、
私たちが普段何気なく使っているパソコンやスマートフォンの安定した動作を支えています。
初めて学ぶと少し難しく感じるかもしれませんが、基本的な仕組みを理解することで、
コンピュータの動作原理についての理解が深まるはずです。
本記事が、MMUやメモリ管理について学ぶ際の一助となれば幸いです。
もし不明点や質問があれば、コメント欄でお気軽にお声がけください。