Linuxのカーネルの開発に関する世界観(ページング・メモリ断片化)です。
メモリは断片化する。小さなプログラムをたくさん実行し、メモリの確保と解放を繰り返していると、まだ空き容量があるにもかかわらず、連続したメモリ領域を確保できなくなる。
メモリを再配置して連続領域を作り出すことをコンパクションと呼ぶが、時間がかかる上にその間プログラムが実行できなくなる。
メモリ空間を「ページ」という単位で管理し、論理アドレスと物理アドレスの「マッピング」を行うことで、断片化の解決ができる。
ページサイズは4096バイト(あるいは2のべき乗)などの固定長の大きさの領域になるため、小さな空き空間が存在しなくなる。また、対応表であるページテーブルによってメモリ領域であるページフレームをマッピングすることで、物理メモリに空いた連続領域がなくても、論理アドレスで連続した空き領域を作り出せる。
ページテーブルにおいて、メモリが有効か無効かを判断するビットのことを「有効ビット」や「存在ビット」と言い、読み込みについては「参照ビット」、書き込みについては「変更ビット」と呼ぶ。
ページにアクセスしたにもかかわらず利用できなかった場合、例外である「ページフォールト」が起きる。
ページング以外の方式として、固定長ではなく可変長の領域を表す「セグメンテーション」という方式がある。物理メモリで断片化が起きても、セグメンテーションテーブルにより論理アドレスには断片化が起きない。セグメンテーション時の例外のことを「セグメンテーションフォールト」と呼ぶ。
(放送大学「コンピュータの動作と管理 ('17)」を参考に執筆しました。)
2023.05.18
自分の書いたブログ「わたしの名はフレイ」2020/06/26より。
Linuxはメモリアドレスをページと呼ばれる小さな単位で管理している。
Linuxでは効率化と使用メモリ領域の削減のために、三段階のページアドレッシングを採用しており、大きなものから順に、ページグローバルディレクトリがあり、その中にページミドルディレクトリがあり、その中にページテーブルがあり、ページテーブルにおいて実際のページ領域をマッピングする。
後日注記:32ビットのプロセッサでは、2段階のページアドレッシングをすることが一般的だったが、64ビットではこれは不十分。2段階ではページテーブルのために大幅に無駄なメモリ領域を確保してしまう。HPのAlphaプロセッサでは3段階のページアドレッシングを採用しており、Linuxではこのモデルを参考にした。
後日注記:最近のLinuxでは、さらに1段階増え、ページグローバルディレクトリ、ページアッパーディレクトリ、ページミドルディレクトリ、ページテーブルの4段階のページアドレッシングとなっている。
(詳しくは詳解 Linuxカーネル 第2版が参考になります。)
(以下は詳解 Linuxカーネル 第2版を参考に執筆しました。)
カーネルは、ページフレームを連続して割り当てる必要があるが、そのためにはメモリ断片化の解決が必要となる。
ここで、バディシステムと呼ばれる方法を使う。これは、1, 2, 4, 8, 16, 32, 64, 128, 512個のように、2を基底とする個数で、サイズごとにリストにまとめて管理するというもの。
たとえば、ページフレームが16個のブロックは、16×212の倍数が先頭アドレスとなる(212の値は4096で、ページサイズのこと)。
ただし、バディシステムは大きなサイズのメモリ確保には適しているが、小さなサイズでは無駄が多い。
SunによってSolaris 2.4のために開発された、スラブアロケータというもっと優れたアルゴリズムもある。
スラブアロケータでは、メモリ領域をコンストラクタ(メモリの確保)とデストラクタ(メモリの解放)の処理をもった、データと関数のあるオブジェクトとして扱う。
(以下はオペレーティングシステム―設計と理論およびMINIXによる実装よりポイントを引用しました。)
ページ置換アルゴリズムとは、ページフォルトが起きた時に、ページを削除して新しいページ空間を作成するために頻繁に使われていないページを選ぶアルゴリズムのこと。
ページ置換アルゴリズムには、そのページが最初に参照されるまでの間に実行を待っている命令数の一番多いページを削除する「最適ページ置換アルゴリズム」のほか、「NRU」「FIFO」「セカンドチャンス」「クロック」「LRU」「NFU」などのアルゴリズムがある。
基本的に、「最適ページ置換アルゴリズム」がもっとも最適だが、実現不可能である。なぜなら、このアルゴリズムに必要となる「ページがいつ参照されるのか」を、ページフォルトが起きた時にOSが知る方法がないからである。しかしながら、ページのすべての参照をあらかじめ記録しておき、このアルゴリズムでの性能をシミュレートすることはできる。よって、もしアルゴリズムの性能に問題があって、「最適ページ置換アルゴリズム」と比べた時にどれだけの性能向上が見込めるか(どれくらいまでは性能を上げることのできる余地があるか)を知ることはできる。
後日注記:Linuxカーネルでは、LRUアルゴリズム(もっとも長い時間使われていないページを削除する)がメモリ管理のために使われている。最新のLinux 6.1では、このアルゴリズムに「世代別グループ管理」を取り入れた「MGLRU」というアルゴリズムが改良されて開発されている。詳しくは以下を参照のこと。
2023.01.09編集
2023.04.14編集
以下の書籍が参考になります。
また、以下のページに参考になる内容があります。日本語版もあります。
MINIX本では、メモリ管理について詳細が記述されています。