一般に、oom-killer は Linux ユーザーの間で評判が悪いです。これが、他に選択肢がまったくない場合にのみ Linux がそれを呼び出す理由の 1 つである可能性があります。最終的にプロセスを強制終了する前に、デスクトップ環境を交換し、ページ全体のキャッシュを削除し、すべてのバッファを空にします。少なくとも、そうなると私は思います。応答しないシステムの前に座ってそれを待つほどの忍耐力はまだありません。
このため、私や他の人々は、oom-killer が reddit r/linux、superuser.com、unix.stackexchange.com に早期に介入するように設定できないか疑問に思いました。
結局のところ、いいえ、それはできません。少なくともカーネル内の oom-killer を使用します。しかし、ユーザー空間では、やりたいことは何でもできます。
アーリールームはシンプルかつ堅実でありたいと考えています。依存関係のない純粋な C で書かれています。広範なテスト スイート (単体テストおよび統合テスト) は Go で作成されています。
Earlyoom は、使用可能なメモリの量と空きスワップを 1 秒あたり最大 10 回チェックします (空きメモリが多い場合はその頻度が低くなります)。デフォルトでは、両方が 10% 未満の場合、最大のプロセス (最も高いoom_score
) が強制終了されます。パーセンテージ値はコマンド ライン引数を介して構成できます。
以下のfree -m
出力では、使用可能なメモリは 2170 MiB、空きスワップは 231 MiB です。
total used free shared buff/cache available
Mem: 7842 4523 137 841 3182 2170
Swap: 1023 792 231
「空き」メモリではなく「利用可能な」メモリがチェックされるのはなぜですか?正常な Linux システムでは、Linux は利用可能なすべての物理メモリを使用してディスク アクセスをキャッシュするため、「空き」メモリはゼロに近いはずです。これらのキャッシュは、別の目的でメモリが必要になったときにいつでも削除できます。
「利用可能な」メモリがこれに相当します。未使用のメモリ、またはすぐに解放できるすべてのメモリを合計します。
「利用可能」列を表示するには、最新バージョンのfree
の Linux カーネル 3.14 以降が必要であることに注意してください。最新のカーネルを使用しているが、 free
のバージョンが古い場合は、 grep MemAvailable /proc/meminfo
から値を取得できます。
利用可能なメモリと空きスワップの両方が、ユーザー空間プロセスで利用可能な合計メモリ (= 合計共有) の 10% を下回ると、カーネルの判断で最も多くのメモリを使用しているプロセスにSIGTERM
シグナルが送信されます ( /proc/*/oom_score
)。
Earlyoom は、次の理由によりecho f > /proc/sysrq-trigger
使用しません。
一部のカーネル バージョン (v4.0.5 でテスト済み) では、カーネル oom キラーを手動でトリガーしてもまったく機能しません。つまり、一部のグラフィックス メモリ (すぐに再度割り当てられる) を解放するだけで、実際にプロセスを強制終了することはありません。私のマシン (Intel 統合グラフィックス) でこれがどのように見えるかをここで確認できます。
この問題は Linux v5.17 (コミット f530243a) で修正されました。
Linux カーネルと同様に、earlyoom は/proc/*/oom_score
読み取ることで被害者を見つけます。
約2 MiB
( VmRSS
) ですが、プライベート メモリ ( RssAnon
) は220 kiB
のみです。残りは、他のプロセスと共有される libc ライブラリ ( RssFile
) です。メモリ不足の状況でも Earlyoom の速度が低下しないように、 mlockall()
使用してすべてのメモリがロックされます。
自分でコンパイルするのは簡単です。
git clone https://github.com/rfjakob/earlyoom.git
cd earlyoom
make
オプション: 統合されたセルフテストを実行します。
make test
Earlyoom をサービスとして登録すると、自動的に開始されます。
sudo make install # systemd
sudo make install-initscript # non-systemd
SELinux が無効になっているシステム (Ubuntu 19.04、Debian 9 ...) の場合、コンテキストの設定の失敗を報告する chcon 警告は無視しても安全であることに注意してください。
Debian 10 以降および Ubuntu 18.04 以降には、Debian パッケージがあります。
sudo apt install earlyoom
Fedora および EPEL を搭載した RHEL 8 の場合は、Fedora パッケージがあります。
sudo dnf install earlyoom
sudo systemctl enable --now earlyoom
Arch Linux の場合は、Arch Linux パッケージがあります。
sudo pacman -S earlyoom
sudo systemctl enable --now earlyoom
他のディストリビューションでの可用性: リポロジーのページを参照してください。
コンパイルしたばかりの実行可能ファイルを起動するだけです。
./earlyoom
メモリとスワップの量、最小値、使用可能なメモリの量、空きスワップの量が表示されます。
./earlyoom
eearlyoom v1.8
mem total: 23890 MiB, user mem total: 21701 MiB, swap total: 8191 MiB
sending SIGTERM when mem avail <= 10.00% and swap free <= 10.00%,
SIGKILL when mem avail <= 5.00% and swap free <= 5.00%
mem avail: 20012 of 21701 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%)
mem avail: 20031 of 21721 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%)
mem avail: 20033 of 21723 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%)
[...]
値が最小値を下回ると、再び最小値を超えるまでプロセスは強制終了されます。すべてのアクションは標準エラー出力に記録されます。 Earlyoom を systemd サービスとして実行している場合は、次を使用して最後の 10 行を表示できます。
systemctl status earlyoom
earlyoom
動作を確認するには、メモリ リークを作成/シミュレートし、 earlyoom
その動作を実行させます。
tail /dev/zero
earlyoom
によってプロセスが強制終了された後にさらにアクション (電子メールの送信など) が必要な場合は、次の方法でログを解析できます。
sudo journalctl -u earlyoom | grep sending
上記のテスト コマンド ( tail /dev/zero
) の出力例は次のようになります。
Feb 20 10:59:34 debian earlyoom[10231]: sending SIGTERM to process 7378 uid 1000 "tail": oom_score 156, VmRSS 4962 MiB
earlyoom
の古いバージョンの場合は、次を使用します。sudo journalctl -u earlyoom | grep -iE "(sending|killing)"
バージョン 1.6 以降、earlyoom はシステム d-bus 経由で強制終了されたプロセスに関する通知を送信できます。有効にするには-n
渡します。
GUI セッションで実際に通知を確認するには、systembus-notify をユーザーとして実行する必要があります。
さらに、earlyoom は、強制終了されたプロセスごとにスクリプトを実行し、 EARLYOOM_PID
、 EARLYOOM_UID
、およびEARLYOOM_NAME
環境変数を介してプロセスに関する情報を提供します。有効にするには、 -N /path/to/script
を渡します。
警告: ドライラン モードの場合、スクリプトは立て続けに実行されます。何らかのレート制限が実装されていることを確認してください。
コマンドライン フラグ--prefer
強制終了を優先するプロセスを指定します。同様に、 --avoid
強制終了を避けるプロセスを指定します。詳細については、https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#--prefer-regex を参照してください。
Earlyoom をシステム サービス (systemd または init.d 経由) として実行している場合は、 /etc/default/earlyoom
で提供されるファイルを使用してその構成を調整できます。ファイルにはコメント内にすでにいくつかの例が含まれており、サポートされているコマンド ライン オプションに基づいて独自の構成セットを構築するために使用できます。次に例を示します。
EARLYOOM_ARGS="-m 5 -r 60 --avoid '(^|/)(init|Xorg|ssh)$' --prefer '(^|/)(java|chromium)$'"
ファイルを調整した後、サービスを再起動するだけで変更が適用されます。たとえば、systemd の場合:
systemctl restart earlyoom
この設定ファイルは、systemd/init.d 以外の Earlyoom インスタンスには影響を与えないことに注意してください。
earlyoom v1.8
Usage: ./earlyoom [OPTION]...
-m PERCENT[,KILL_PERCENT] set available memory minimum to PERCENT of total
(default 10 %).
earlyoom sends SIGTERM once below PERCENT, then
SIGKILL once below KILL_PERCENT (default PERCENT/2).
-s PERCENT[,KILL_PERCENT] set free swap minimum to PERCENT of total (default
10 %).
Note: both memory and swap must be below minimum for
earlyoom to act.
-M SIZE[,KILL_SIZE] set available memory minimum to SIZE KiB
-S SIZE[,KILL_SIZE] set free swap minimum to SIZE KiB
-n enable d-bus notifications
-N /PATH/TO/SCRIPT call script after oom kill
-g kill all processes within a process group
-d, --debug enable debugging messages
-v print version information and exit
-r INTERVAL memory report interval in seconds (default 1), set
to 0 to disable completely
-p set niceness of earlyoom to -20 and oom_score_adj to
-100
--ignore-root-user do not kill processes owned by root
--sort-by-rss find process with the largest rss (default oom_score)
--prefer REGEX prefer to kill processes matching REGEX
--avoid REGEX avoid killing processes matching REGEX
--ignore REGEX ignore processes matching REGEX
--dryrun dry run (do not kill any processes)
--syslog use syslog instead of std streams
-h, --help this help text
詳細についてはマニュアルページを参照してください。
バグレポートとプルリクエストは github 経由で受け付けます。特に喜んでお受けいたします
v1.8.2、2024-05-07
earlyoom.service
systemd ユニットファイルの修正process_mrelease
許可されたシステムコールに追加 (コミット)IPAddressDeny
構文を修正 (コミット)-p
(コミット) を許可するv1.8.1、2024-04-17
v1.8、2024-04-15
user mem total
/ meminfo_t.UserMemTotal
を導入し、それに基づいて MemAvailablePercent を計算します (コミット、詳細はマニュアルページを参照)process_mrelease
を使用する (#266)NO_COLOR
サポート (https://no-color.org/)--sort-by-rss
を追加してください。ありがとう @RanHuang!これにより、acc を強制終了するプロセスが選択されます。最大の oom_score ではなく最大の RSS に設定されます。v1.7、2022-03-05
-N
フラグを追加して、プロセスが強制終了されるたびにスクリプトを実行します (コミット、マニュアルページセクション)-g
フラグを追加してプロセス グループ全体を強制終了します (#247)-i
フラグを削除します (互換性のために無視されます)。Linux カーネル 5.9 以降では正しく動作しません (#234)v1.6.2、2020-10-14
1.6.1、2020-07-07
1.6、2020-04-11
notify-send
GUI 通知ロジックをdbus-send
/ systembus-notify に置き換えます (#183)-n
/ -N
で新しいロジックが有効になりました/proc
適切に処理する (問題 #184)v1.5、2020-03-22
-p
: oom_score_adj を-1000
ではなく-100
に設定します (#170)-M
と-m
、および-S
と-s
両方の使用を許可します。低い方の値 (パーセンテージに変換) が使用されます。earlyoom.default
のメモリレポート間隔を 1 分ではなく 1 時間に設定します (#177)v1.4、2020-03-01
uid
ログに記録します。make test
)cppcheck
実行しますmake bench
)earlyoom.service
の root 権限を削除します。v1.3.1、2020-02-27
v1.3、2019-05-26
v1.2、2018-10-28
-k
、現在は互換性のために無視されています) (問題 #80)v1.1、2018-07-07
-h
に加えて--help
も受け入れます-S
(コミット) によるゼロ除算の可能性を修正v1.0、2018-01-28
--prefer
および--avoid
オプションを追加しました (@TomJohnZ)-n
および-N
を追加します。 v0.12: -M
および-S
オプションを追加 (@nailgun); man ページを追加し、Makefile をパラメータ化します (@yangfl)
v0.11: get_entry_fatal の未定義の動作を修正 (リターン、コミットの欠落)
v0.10: パッケージ化を容易にするために Makefile の VERSION 変数をオーバーライドできるようにし、 -v
コマンドライン オプションを追加します
v0.9: すべてのプロセスの oom_score が 0 の場合、VmRss を使用して被害者を見つける
v0.8: カーネルが MemAvailable を提供しない場合は推測値を使用する
v0.7: VmRSS の代わりに oom_score で被害者を選択し、オプション-i
と-d
を追加
v0.6: コマンドラインオプション-m
、 -s
、 -k
を追加
v0.5: スワップサポートを追加
v0.4: SysV init スクリプトを追加 (@joeytwiddle に感謝)、 /proc/meminfo
から新しいMemAvailable
を使用 (Linux 3.14 以降、コミットが必要)
v0.2: systemd ユニットファイルを追加
v0.1: 初期リリース