Linuxカーネルにはコントロールグループ(cgroup)という機能があります。この機能では、プロセスのグループに対してCPU時間やメモリといったリソースを割り当てることができます。
この記事ではArmadillo-X1・Armadillo-IoT G3/G3Lを対象に、大きくメモリを使用するプロセスに対しメモリ使用量を制限する方法を紹介します。
1. はじめに
大きくメモリを使用するがOOM Killerの対象から外したい場合は"oom_score_adj"を設定を行います。方法は以下の記事を参照してください。
ただし、対象から外したプロセスが依然としてメモリの確保を続ける場合、いずれメモリは枯渇し、OOM Killerにより次は別のプロセスが終了させられます。 cgroupを利用することで、プロセスに対しメモリ使用量の上限を設定できます。
2. カーネルコンフィグの変更
デフォルトでcgroupは有効化されていますが、cgroupのメモリ管理機能は有効化されていないため、カーネルコンフィギュレーションを行います。
カーネルコンフィグで"CONFIG_RESOURCE_COUNTERS"と"CONFIG_MEMCG"を有効化します。
General setup -> Control Group support -> Resource counters <= 有効化 -> Memory Resource Controller for Control Groups <= 有効化
コンフィギュレーションを変更してLinuxカーネルイメージをカスタマイズする方法は以下を参照してください。手順はArmadillo-IoT G3/G3Lも同じです。
3. cgroupでメモリ使用可能量を制限する
手順1.で作成したカーネルで起動すると、/sys/fs/cgroup/memory というディレクトリが生成されます。
この階層以下のファイルへの書き込みや、ディレクトリ作成によって、cgroupのメモリ管理機能を利用できます。
cgroupではプロセスのグループに対してリソース管理を行います。
この階層へディレクトリを作成することで、メモリ割り当てを管理するプロセスのグループを作成できます。
ここでは、"foo"という名前のグループを作成します。
[armadillo]# mkdir /sys/fs/cgroup/memory/foo
グループへプロセスを追加するにはグループのディレクトリ内のtasksというファイルへプロセスIDを書き込みます。
例えば、プロセスID 123 のプロセスに対してメモリ管理を行いたい場合、以下のコマンドを実行します。
[armadillo]# echo 123 > /sys/fs/cgroup/memory/foo/tasks
最後に、グループで使用できるメモリ上限はmemory.limit_in_bytesファイルへ書き込みます。
例えば、100MBの制限を行う場合、以下のコマンドを実行します。
[armadillo]# echo 100m > /sys/fs/cgroup/memory/foo/memory.limit_in_bytes
4. おわりに
こちらの記事と組み合わせることで、「特定のプロセスが使用できるメモリ上限を設定し、OOM Killerの対象から外す」事ができます。
なお、cgroupのメモリ管理では他にも
- OOM時にOOM Killerを発動させるのではなく、メモリが確保できるまで待機させる
- メモリを確保しようとするプロセスがOOM状態の通知を受信する
なども可能です。
詳しくは以下の記事を参照してみてください。