cgroupsのmemoryサブシステムを使用して、コントロールグループのメモリ使用量の上限を設定します。
コントロールグループにタスクを登録
メモリ使用量の上限となるmemory.max_usage_in_bytesはroot groupには設定できないので、
下階層にコントロールグループを作成し、現在のシェルから実行されるタスクが登録されるようにします。
# mount -t cgroup -o memory none /cgroup/
# mkdir /cgroup/hoge
# echo $$ > /cgroup/hoge/tasks
メモリを消費するタスクの作成
下記のようなメモリを消費するテストプログラムを作成します。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define MB 1024*1024
int main(int argc, char *argv[])
{
char *p;
int malloc_size = 10 * MB;
while(1)
{
p = (char *)malloc(malloc_size);
memset(p, 0, malloc_size);
sleep(1);
}
return 0;
}
メモリ使用量制限しない場合
テストプログラムを実行し、メモリ使用量を確認します。
どんどんメモリ使用量が増え続けて、最終的にはOoM Killerによって殺されました。
メモリ使用量制限する場合
memory.max_usage_in_byteにメモリ使用量の上限を設定します。
単位はバイト数またはMやGで指定できます。
今回は200MBを上限に設定します。
# echo 200M > /cgroup/hoge/memory.limit_in_bytes
テストプログラムを実行し、メモリ使用量を確認します。
設定した上限に達した辺りでテストプログラムがOoM Killerによって殺されました.
OoM Killerの有効化/無効化
先ほどはメモリ使用量上限に達した際にタスクはOoM Killerによって殺さましたが、
memory.oom_controlにてOoM Killerの有効化(0)/無効化(1)が設定できます。
デフォルトはOoM Killer有効化されています。
無効化した場合、メモリーを使用しようとするタスクは追加のメモリーが解放されるまで一時停止されます。
実際に無効化して場合を確認してみます。
# echo 1 > /cgroup/hoge/memory.oom_control
テストプログラムを実行し、メモリ使用量を確認します。
上限辺りのままタスクが停止していることが確認できました。