2009-12-13

Linuxのメモリ管理について

Linuxのメモリ管理について勉強中なので、簡単なまとめをメモ。


仮想アドレスと実アドレス

多くのマルチタスクOSでは仮想アドレス空間を持っています。仮想アドレス空間の仕組みを利用すれば、物理メモリ上では不連続にマッピングされたページでも、プロセスからは連続した領域として扱うことができます。
ここでいうページとは、メモリを一定の大きさに区切って管理するための単位のことで、4Kバイトのことが多いようです。仮想アドレスと実アドレスへの変換はページ変換テーブルを用いて行われます。


実メモリの管理

実メモリはバディシステムと呼ばれる仕組みで管理されています。
バディシステムは空きページを2の冪剰の単位で分割したページフレームのリストで管理します。たとえば、4ページ分の連続メモリを確保したい場合は、まずオーダー2(2の2剰個の連続ページ)のリストから空きを探し、無かった場合は一つ上のオーダーから探します。そこで空きが見つかった場合は、そこを確保して半分に分割し、残った半分をオーダー2の空きリストに追加します。空きが見つからなかった場合は、さらに上のオーダーを再帰的に探索していきます。割り当てられる領域が見つからなかった場合はoom(out of memory) killerが実行されます。

空きページ状況は/proc/buddyinfoから参照できます
各オーダー毎につながっている空きリストの数が表示されます。
% cat /proc/buddyinfo
Node 0, zone      DMA    127    117     23      6      1      0      0      1      0      0      0
Node 0, zone   Normal    427    365     30      4      2      1      0      0      1      0      0


再起動するとフラグメンテーションが解消されていることが確認できます。
% cat /proc/buddyinfo
Node 0, zone      DMA      3      4      4      3      4      2      2      1      1      1      2
Node 0, zone   Normal      5      0      3      1      1      2      2      8      3      4     12

メモリをページ単位だけで扱うのは不便なので、より柔軟な割り当て方法としてスラブアロケータという仕組みがあります。
スラブアロケータはバディシステムから確保したメモリをキャッシュと呼ばれる同じ種類のオブジェクトの集合に分割します。ここでいうキャッシュとは、バディシステムから確保された連続した物理ページのあつまりで、キャッシュに対して割り当てられたオブジェクトの入れ物をスラブといいます。

スラブアロケータの使用状況は/proc/slabinfoを参照することで確認できます。
tunablesの値は変更することも可能です。詳細は以下の参考文献を参照してください。
limit フィールドは、CPU ごとにキャッシュに入れるオブジェクトの最大数を指定します。batchcount フィールドは、CPU 単位のキャッシュが空になったときにそこへ転送するグローバル・キャッシュ・オブジェクトの最大数です。shared パラメーターは、SMP (Symmetric MultiProcessing) システムに対する共有動作を指定します。
http://www.ibm.com/developerworks/jp/linux/library/l-linux-slab-allocator/


 ここまで調べて疲れてきたので、以下の内容はあとで加筆・修正するかもしれません。

プロセス空間の管理

プロセスに仮想アドレスを割り当てる際には様々なテクニックが用いられています。詳細は省きますが、以下のようなテクニックがあります。

スワップ
デマンドページング
コピーオンライト
ファイルマップ


プロセス空間の割り当ては、以下のようなシステムコールを用いて行うことができます。

fork
exec
mmap
brk

ページの回収

回収の対象はプロセス空間とページキャッシュで使用している実ページのうち、最近もっとも使用されていないページです。カーネルで使用しているページは回収の対象にはなりません。

処理の流れとしては以下のようになります。

* 最近参照されたかどうかチェック。
ページキャッシュの場合は、カーネルはPG_refferencedフラグをみることで知ることができます。プロセス空間にマップされたページは、ページテーブルエントリにハードウェアによってアクセスされたことが記録されるため、そこを参照することで知ることができます。
* inactiveキューに移動
* スワップ領域の割り当て
* アンマップ処理
* ダーティページの書き戻し
* ページの解放


Linuxカーネル2.6解読室   [本]
Linuxカーネル2.6解読室   [本]

0 件のコメント:

コメントを投稿

ZenBackWidget