物理RAM
実行中に使うコードとデータを保持します。Linuxはpage frameへ分け、用途を追跡します。
アドレスを変換し、RAMを割り当てて回収する
Linuxは、各プロセスに独立したアドレス空間を見せながら、限られた物理RAMを割り当てます。ファイルの読み書きとカーネル内部のメモリも、同じ管理機構につながっています。
実行中のプログラム、Linuxカーネル、デバイスドライバは、同じコンピューターの物理RAM物理RAM実行中のコードやデータを保持し、CPUから読み書きされる有限の記憶領域。を使います。物理RAMには上限があり、必要なデータを置く場所と、各プロセスがアクセスできる範囲をLinuxが管理します。
プロセスへ物理RAMの位置を直接渡すと、別のプロセスやカーネルの領域まで読み書きできてしまいます。Linuxは仮想アドレス空間仮想アドレス空間一つのプロセスが使用できる仮想アドレスの範囲。をプロセスごとに用意します。CPU内でアドレス変換を行う回路をMMUMMUCPUが仮想アドレスを物理アドレスへ変換するための回路。と呼びます。Linuxが変換規則を用意し、MMUが命令の実行中に変換することで、アクセスできる範囲と物理RAMの対応を制御します。
実行中に使うコードとデータを保持します。Linuxはpage frameへ分け、用途を追跡します。
プログラムから見えるアドレスの範囲です。領域ごとに読み取り、書き込み、実行の権限を持ちます。
プログラムは、必要なメモリ量をbytebyteメモリの大きさを数える基本単位。Linuxでは1 byteは8 bit。で指定し、使える範囲の先頭を示すポインタポインタメモリ上の位置を示すアドレスを保持する値。を受け取ります。mallocmalloc必要なbyte数を指定し、利用できるメモリ領域を得るCライブラリ関数。、mmapmmapプロセスの仮想アドレス空間へ、新しい範囲を追加するシステムコール。、pagepage仮想アドレス空間と物理RAMを、一定の大きさに区切って管理する単位。は、この処理の異なる段階を指します。
char *buffer = malloc(10000);
buffer[0] = 'A';
free(buffer);10000は必要な大きさをbytebyteメモリの大きさを数える基本単位。Linuxでは1 byteは8 bit。で指定しています。bufferには、確保した範囲の先頭を示すポインタポインタメモリ上の位置を示すアドレスを保持する値。が入ります。
mallocは、プロセス内で再利用できる空き領域を探します。
空き領域が足りなければ、glibcなどのmalloc実装はbrkbrkプロセスのheapの終端を動かし、利用できる仮想アドレス範囲を広げたり縮めたりするシステムコール。やmmapmmapプロセスの仮想アドレス空間へ、新しい範囲を追加するシステムコール。を使ってLinuxへ範囲を求めます。
戻り値は仮想アドレスです。プログラムはこの値を使って、確保した範囲を読み書きします。
書き込むpageに対応がなければページフォールトが起きます。Linuxはpage frameを用意し、ページテーブルを更新します。
mallocが受け取る大きさはbyte単位です。LinuxとCPUは、その範囲をpage単位で物理RAMへ対応づけます。
実行ファイルのcodeとdata、動的に確保するheap、共有ライブラリやmemory-mapped files、各スレッドのstackは、仮想アドレス空間内の領域として管理されます。攻撃者が配置を予測しにくくするため、Linuxは起動のたびに一部の位置を変えます。この仕組みをASLRASLRプロセスの仮想アドレス空間で、コードやデータの配置を実行ごとに変える仕組み。と呼びます。実際の配置は、CPUアーキテクチャや実行ファイルの構成によっても変わります。
Linuxは、各領域の開始位置、終了位置、アクセス権、対応するファイルなどを記録します。
領域として存在していても、すべてのpageに物理RAMが割り当てられているとは限りません。対応関係はpage単位で作られます。
プログラムの命令が読み書きする位置は仮想アドレス仮想アドレスプロセスのアドレス空間で、命令がメモリを参照するときに使うアドレス。です。CPUのMMUはページテーブルページテーブル仮想アドレスと物理RAMの対応を記録する表。を使い、その仮想アドレスを物理RAMのpage frameとpage内の位置へ変換します。
物理RAMはpagepage仮想アドレス空間と物理RAMを、一定の大きさに区切って管理する単位。単位で管理されます。x86-64では4 KiBが広く使われますが、pageの大きさはCPUアーキテクチャとカーネル設定によって変わります。仮想アドレス上で隣り合うpageを、物理RAM上でも隣り合わせに置く必要はありません。
mallocなどのライブラリやmmapがアドレス範囲を用意しても、その全域へすぐ物理RAMを割り当てるとは限りません。プロセスが初めてpageへアクセスするとページフォールトページフォールト現在のページテーブルだけではメモリアクセスを完了できないときにCPUが起こす例外。が起き、Linuxがアクセスの正当性とpageの準備方法を判断します。ページフォールトは、必要なpageをその時点で用意する通常の処理にも使われます。
命令が仮想アドレスを読み書きします。
page table entryがない場合や、書き込み権限などを確認する場合にCPUが例外を発生させます。
anonymous memoryanonymous memory特定のファイルを保存元として持たないメモリ。へpage frameを割り当てる、ファイルの内容をpage cachepage cacheファイルの内容をRAMへ保持し、読み書きを速くする仕組み。へ読む、copy-on-writeで複製するなどの処理を選びます。
ページテーブルを更新し、完了できなかったメモリアクセスをもう一度実行します。
anonymous memoryanonymous memory特定のファイルを保存元として持たないメモリ。は、ファイルを保存元に持たないpageです。内容を残したままRAMを空ける場合はswapswapRAM上のanonymous memoryを一時的に退避できる、ストレージ上の領域。へ書き出します。
page cachepage cacheファイルの内容をRAMへ保持し、読み書きを速くする仕組み。は、ファイルの内容をRAMへ保持します。変更のないpageは破棄してもファイルから再読込できます。変更済みならストレージへ書き戻します。
reclaimreclaim空きRAMを増やすため、使用中のpageを回収候補から選んで解放する処理。は、page cacheの破棄や書き戻し、anonymous memoryのswapを通じて空きRAMを増やします。頻繁に参照されるpageを回収すると、直後に再読込が必要になり性能が落ちるため、回収候補の選択が必要です。
Multi-Gen LRUMulti-Gen LRUpageを参照時期の世代に分け、reclaimの候補を選ぶ仕組み。は、参照された時期に応じてpageを複数の世代へ分け、古い世代から回収候補を探します。pageの種類と参照状況を追跡し、最近使われたpageをRAMへ残しやすくします。
Googleによる開発の記録を見る空きpageがlow watermarkを下回ると起床し、プロセスの割り当てと並行してreclaimを進めます。
空きpageがさらに減ると、メモリを要求した処理自身がreclaimを行い、割り当てを待ちます。
OOM killerOOM killerreclaimで必要な空きRAMを作れないとき、プロセスを終了させてシステムを動かし続ける仕組み。は、Linuxが選んだプロセスを終了させてメモリを解放します。
/proc/PID/oom_score値が高いプロセスほど終了対象に選ばれやすくなります。主な基準は、利用を許された範囲に対するメモリ使用量です。
/proc/PID/oom_score_adj-1000から1000までの値を加えて選ばれやすさを調整します。-1000に設定したプロセスはOOM killerの対象から外れます。
foliofolio連続する一つ以上のpageを、まとまりとして扱うための型。は、連続する一つ以上のpageをまとまりとして扱う型です。Linux 5.16で導入され、page cacheなどの処理で使われています。
1 pageだけを表すfolioもあります。複数のpageを含む場合は、検索やロックなどの処理回数を減らせます。
カーネルは、プロセスの情報、ファイルの情報、ネットワークパケットなど、多数の小さなオブジェクトを作ります。物理メモリのpageをそのまま一つずつ渡すと無駄が大きいため、二段階で割り当てます。
page allocatorは、空いている物理pageを1、2、4、8…pageの連続した領域として管理します。必要な大きさがなければ大きい領域を半分に分け、隣り合う同じ大きさの領域が両方とも空けば再び結合します。この管理方法をbuddy allocatorbuddy allocator空いている物理pageを、2の累乗個からなる連続領域として管理する仕組み。と呼びます。
buddy allocatorが、必要な数の連続するpageを割り当てます。
SLUBSLUBカーネル内の小さなオブジェクトを割り当てる仕組み。はpageを小さな区画へ分け、同じ型のオブジェクトとして再利用します。
必要な大きさに近い区画を受け取ります。