第5章メモリ管理
メモリに関する統計情報
total
システムに搭載されている全メモリの量
free
見かけ上の空きメモリ
buff/cache
バッファキャッシュ、およびページキャッシュが利用するメモリ
available
実質的な空きメモリ
Out Of Memory
メモリ使用量が増えてくると、空きメモリが少なくなると、メモリ管理システムはカーネル内の解放可能なメモリ領域を解放する。
Out Of Memory(OOM)
使用量が増え続けた後の、何をするにもメモリが足りず身動きが取れない状態
OOMになると、適当なプロセスを選んで強制終了することでメモリ領域を解放する機能が動作する。(OOM killer)
sytctlのvm.panic_on_oomのパラメータをデフォルトの0から1に変更することがある(OOM発生時にOOM killer発動からOOM発生時システム強制終了に変更)。
単純なメモリの割り当て
プロセス生成後の動的メモリ割り当て
プロセスはカーネルに対して、メモリ獲得用のシステムコールを発行しメモリ割り当ての要求を出す。
カーネルは要求が来たら必要なサイズを空きメモリ領域から切り出して、その先頭アドレスを返す。
以下の3つの問題がある
メモリの断片化
バラバラの位置に領域があるためメモリ確保に失敗すること。
複数領域を1組として扱うことはできない。
プログラムではメモリ獲得のたびに得られたメモリが何この領域にまたがっているかを意識して使わなければならないので不便
各空き領域より大きなデータを作ることができない。
別用途のメモリにアクセスできてしまう
カーネルや他のプロセスが使用するアドレスを指定さえすればアクセスできるので、データ破壊の可能性がある。
マルチプロセスの扱いが困難
仮想記憶
ファイルマップ
プロセスがファイルにアクセスした時、ファイルの領域を仮想アドレス空間上にメモリマップする。
プロセス生成時にプロセスの仮想アドレス空間内のコード領域やデータ領域に相当するページに、プロセスがこの領域を獲得したという情報を記録する。
プログラムがエントリポイントから実行を開始する際に、エントリポイントに対応するページ用の物理メモリを割り当てる。
プログラムがエントリポイントにアクセス
CPUがページテーブルを参照し、エントリポイントが属するページに対応する仮想アドレスが物理アドレスと紐づいていないことを検出
CPUでページフォールトが発生
カーネルのページフォールトハンドラが1でアクセスしたページに物理メモリを割り当てた上でページテーブルを書き換える
ユーザモードに戻ってプロセスが実行を継続する
仮想メモリの枯渇
プロセスが仮想アドレス空間一杯まで仮想メモリを使い切った状態でメモリを獲得しようとすると発生する。
物理メモリの残りメモリ量に関わらず発生する。
コピーオンライト
親子のプロセスで共有されたページに対してどちらかが更新しようとした場合に、以下の流れで共有を解除する。
ページへの書き込みは許可されていないので、書き込み時にCOU上でページフォールトが発生。
CPUがカーネルモードに遷移しカーネルのページフォールトハンドラが起動。
ページフォールトハンドラはアクセスされたページを別の場所にコピーして書き込みしようとしたプロセスに割り当てた上で内容を書き換える。
親プロセスと子プロセスそれぞれについて、共有が解除されたページに体操するページテーブルエントリを更新する。
書き込みしたプロセス側のエントリは、新たに与えられた物理ページと紐付けた上で書き込みを許可する。
もう一方のプロセス側のエントリについても書き込みを許可する。
共有が解除されたページにはそれぞれ読み書きが自由にできる。
システムのメモリが枯渇した状態で物理メモリを獲得すると、ページフォールトが発生。
物理メモリには空きが無いので、カーネルは使用中の物理メモリの一部をスワップ領域に退避。
階層型ページテーブル
x86_64アーキテクチャのページテーブルは階層構造になっており、メモリ量を節約している。
ヒュージページ
通常より大きなサイズのページを使うことで、プロセスのページテーブルに必要なメモリ量を減らせる。