従来のOOM killerが抱える限界とsystemd-oomdの登場背景
Linuxカーネルに組み込まれたOOM(Out of Memory)killerは、物理メモリとスワップが枯渇した時点でプロセスを強制終了させる最後の砦です。しかし運用現場では、「カーネルが選んだ終了対象がデータベース本体だった」「OOM killerが発動するまでシステムが数分間フリーズ状態になった」といったつまずきが一般的に報告されています。
カーネルOOM killerの根本的な問題は、介入タイミングが「手遅れ寸前」である点です。カーネルはメモリ割り当て要求が失敗してはじめてOOM killerを起動します。その時点ではすでにページキャッシュが消耗し、スワップが逼迫し、システム全体がスラッシングに陥っている場合が少なくありません。終了対象の選定もOOMスコア(/proc/<pid>/oom_score)に基づく推測であり、サービスの重要度を事前に反映させにくい構造です。
こうした課題を受け、systemd v247(2020年末)でsystemd-oomdがuserspace OOM管理デーモンとして同梱されました。カーネルが限界を超えてから動くのではなく、PSI(Pressure Stall Information)という圧力メトリクスをもとにメモリ逼迫を予兆段階で検知し、cgroupsの単位で計画的にプロセスを終了させる設計です。
PSI(Pressure Stall Information)の仕組みと閾値設計の考え方
PSIはLinux 4.20(2019年初頭)から導入されたカーネル機能で、CPU・メモリ・IOそれぞれについて「プロセスがリソース待ちで止まっていた時間の割合」を/proc/pressure/以下のファイルで公開します。メモリに関しては/proc/pressure/memoryが対象で、some(少なくとも1つのタスクが待機)とfull(すべてのタスクが待機)の2種類の指標が10秒・60秒・300秒の移動平均として記録されます。
systemd-oomdはこのPSI値を一定間隔でポーリングし、設定した閾値を超えた状態が一定時間続いた場合にcgroup内のプロセス終了を判断します。主要な設定パラメータは以下のとおりです。
- DefaultMemoryPressureLimit:メモリPSI(some平均)の閾値。デフォルト値は60(%)。
- DefaultMemoryPressureDurationSec:閾値超過が続く必要がある時間。デフォルトは30秒。
- DefaultSwapUsedLimit:スワップ使用率の上限。デフォルトは90(%)。
閾値設計で重要なのは「早めに介入させるか、誤検知を避けるか」のトレードオフです。メモリPSIが60%を超えるケースは、バッチジョブの突発的なメモリ消費や大量ファイルの読み込みでも一時的に発生します。本番サービスで誤った終了を防ぐには、DefaultMemoryPressureDurationSecを長めに設定(想定例:60〜120秒)して一時的な急騰に反応しないようにする方法があります。一方でスワップ枯渇は急速に進むことが多いため、DefaultSwapUsedLimitを80〜85%に下げて早期介入させる判断も合理的です。
また、すべてのcgroupをsystemd-oomdの管理対象にするかどうかも検討が必要です。ユニットファイルにManagedOOMMemoryPressure=killまたはManagedOOMSwap=killを明示することでそのスライス・サービスを管理対象に含められます。逆にManagedOOMMemoryPressure=auto(デフォルト)のままにすると、user.sliceやsystem.sliceの上位設定が引き継がれます。
設定ファイルの記述と有効化手順
メイン設定ファイルは/etc/systemd/oomd.confです(存在しない場合は/usr/lib/systemd/oomd.confがデフォルトとして参照されます)。設定変更の想定例を以下に示します。
[OOM]
SwapUsedLimit=85%
DefaultMemoryPressureLimit=60%
DefaultMemoryPressureDurationSec=60s
設定変更後はデーモンをリロードします。
sudo systemctl daemon-reload
sudo systemctl restart systemd-oomd
管理対象サービスを明示的に指定するには、対象サービスのユニットファイルまたはdropinファイルに設定を追加します。
# /etc/systemd/system/myapp.service.d/oomd.conf
[Service]
ManagedOOMSwap=kill
ManagedOOMMemoryPressure=kill
ManagedOOMMemoryPressureLimit=50%
ManagedOOMMemoryPressureLimitをサービス単位で設定すると、グローバルのDefaultMemoryPressureLimitを上書きできます。重要度の高いサービスは閾値を低め(想定例:40〜50%)にして早期介入させ、バッチジョブは高め(70〜80%)にするといった使い分けが可能です。現在の管理対象と状態を確認するにはoomctlコマンドを使います。
sudo oomctl status
出力には管理対象のcgroup、PSI値、スワップ使用率などが一覧表示されます。有効化直後にこのコマンドで対象スライスが正しく認識されているかを確認しておくと、想定外の範囲が管理対象になるトラブルを防げます。
ログの検証と動作確認の手順
systemd-oomdが実際に動作したかどうかはjournalctlで確認します。
sudo journalctl -u systemd-oomd -e --no-pager
終了アクションが発生した場合、以下のようなメッセージが記録されます(メッセージはバージョンによって表記が異なる場合があります)。
systemd-oomd[PID]: Killed cgroup /system.slice/myapp.service due to memory pressure
PSI値の現在値をリアルタイムで観察するには/proc/pressure/memoryを直接参照します。
watch -n 2 cat /proc/pressure/memory
出力のsome avg60がsystemd-oomdのDefaultMemoryPressureLimitと照合されます。通常稼働時にこの値がどの水準で推移しているかをあらかじめ記録しておくと、閾値チューニングの基準値として活用できます。
systemd-oomdによる終了とカーネルOOM killerによる終了は区別できます。カーネルOOM killerはdmesgやjournalctl -kにOut of memory: Killed processと記録します。一方、systemd-oomdの終了はsystemdのジャーナルにのみ記録されます。インシデント発生時は両方のログを合わせて確認し、どちらが動作したかを特定することが重要です。
切り戻しと運用上の注意点
systemd-oomdを無効化するには以下のコマンドを実行します。
sudo systemctl disable --now systemd-oomd
無効化後はカーネルOOM killerだけが動作します。メモリ逼迫が長時間続いた後にカーネルが介入するパターンに戻るため、対応ウィンドウが狭くなる点は認識しておく必要があります。特にスワップが少ない環境では、早期介入の機会が失われることを考慮してください。
よくあるつまずきとして「OOM管理デーモンの二重起動」があります。earlyoomのような別のuserspace OOMデーモンと同時稼働させると、同じcgroupに対して二重に介入する可能性があります。systemd-oomdを採用する場合はearlyoomや類似ツールを停止・無効化することを推奨します。
コンテナ環境との相互作用にも注意が必要です。DockerやPodmanのコンテナはcgroupを独自に管理します。systemd-oomdはcgroupsのツリーを参照するため、コンテナランタイムの設定によっては管理対象の境界が意図と異なる場合があります。cgroupv2が有効な環境ではコンテナも含めてcgroupツリーが統一されるため、systemd-oomdとの親和性が高まります。cgroupv1環境ではPSIメトリクスが取得できないため、systemd-oomdはそもそも動作しません。
2026年時点の主要ディストリビューションでの現状と差分
Ubuntu 22.04 LTS / 24.04 LTS:Ubuntu 22.04以降ではsystemd-oomdがデフォルトで有効化されています。user.sliceとsystem.sliceの両方にManagedOOMSwap=killが設定済みのため、スワップ使用率が閾値を超えると自動的に介入します。既存の本番サーバでUbuntu 22.04以降を使用している場合は、すでにsystemd-oomdが動作している可能性があります。oomctl statusとjournalctl -u systemd-oomdで現状を把握してから閾値チューニングに入るのが安全です。
RHEL 9 / Rocky Linux 9 / AlmaLinux 9:RHEL 9ではsystemd v250以降が採用されており、systemd-oomdパッケージは利用可能ですが、デフォルトでは無効になっています。使用する場合は明示的にsystemctl enable --now systemd-oomdを実行する必要があります。cgroupv2がデフォルト有効なため、PSIメトリクスも標準で利用できます。
Debian 12(Bookworm):systemd v252を採用しており、systemd-oomdは利用可能です。ただしUbuntuとは異なりデフォルトでは有効化されておらず、手動で起動・設定する運用になります。
Fedora 40以降:Fedoraはsystemd-oomdの積極的な採用を継続しており、cgroupv2+PSIの組み合わせが安定して動作します。サーバ用途では閾値の適切な調整が引き続き推奨されています。
共通して注意すべき点として、古いカーネル(4.20未満)またはsystemd.unified_cgroup_hierarchy=0のブートパラメータが設定されている環境では、cgroupv2+PSIが使えないためsystemd-oomdは機能しません。現行の主要ディストリビューションではcgroupv2がデフォルトになっているため、新規構築環境では意識しなくても問題ないケースが大半です。一方、旧環境からの移行時はカーネルパラメータの確認を先行させる必要があります。cat /sys/fs/cgroup/cgroup.controllersでcgroupv2が有効かどうかを手軽に確認できます。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
PR・広告
[試して理解]Linuxのしくみ 増補改訂版(Amazon)
プロセス・権限・ファイルシステムなどLinux内部を図解で理解できる一冊。運用判断の勘所に。
※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。
