Linuxは、メモリが不足するかどうかを確認せずにプロセスを強制終了しますか?


66

メモリを大量に消費するいくつかのプログラム(2〜5 GB)を連続して実行するコマンドを使用して、シェルスクリプトを実行していました。スクリプトの進行状況を確認するために戻ったときKilled、端末から報告されたように、プロセスの一部がであることに驚いた。いくつかのプログラムはKilled、後で開始されるプログラムの前にすでに連続して完了していましたが、その後、すべてのプログラムはセグメンテーションフォールトで失敗しました(コードのバグが原因である場合も、そうでない場合もあります)。

私が使用していた特定のクラスターの使用履歴を調べたところ、誰かが同時に複数のメモリー集約型プロセスを実行し始め、その結果、クラスターで利用可能な実メモリー(および場合によってはスワップスペース)を使い果たしたことがわかりました。私の知る限り、これらのメモリ集約型プロセスは、プログラムで問題が発生し始めたのとほぼ同時に実行を開始しました。

Linuxでプログラムがメモリ不足になると、プログラムが強制終了する可能性はありますか?そして、私が後で得たセグメンテーション違反は、プログラムの実行に使用できるメモリの不足によるものである可能性があります(コードのバグではなく)。


2
メモリを割り当てるときに、メモリが正常に割り当てられたかどうかを確認するステートメントがありますか?これは、コードにバグがあるのか​​、それともシステムのメモリ不足が原因であるのかを知る手がかりになるはずです。
unxnut

回答:


72

できる。

Linuxで発生する可能性のある2つの異なるメモリ不足状態があります。発生するものはsysctl vm.overcommit_memory/proc/sys/vm/overcommit_memory)の値によって異なります

はじめに:
カーネルは、いわゆる「メモリーオーバーコミット」を実行できます。これは、カーネルがシステムに実際に存在するよりも多くのメモリをプログラムに割り当てる場合です。これは、割り当てられたすべてのメモリをプログラムが実際に使用しないことを期待して行われます。これは非常に一般的な現象です。

overcommit_memory = 2

ときovercommit_memoryに設定され2、カーネルはまったくオーバーコミットを実行しません。代わりに、プログラムにメモリが割り当てられると、そのメモリを持っていることが保証されます。システムに割り当て要求を満たすのに十分な空きメモリがない場合、カーネルは要求に対して失敗を返すだけです。状況を適切に処理するのはプログラム次第です。本当に失敗したときに割り当てが成功したことを確認しない場合、アプリケーションはしばしばセグメンテーション違反に遭遇します。

セグメンテーション違反の場合、次のような行が出力に表示されdmesgます。

[1962.987529] myapp[3303]: segfault at 0 ip 00400559 sp 5bc7b1b0 error 6 in myapp[400000+1000]

これat 0は、アプリケーションが初期化されていないポインターにアクセスしようとしたことを意味します。これは、失敗したメモリー割り当て呼び出しの結果である可能性があります(しかし、これが唯一の方法ではありません)。

overcommit_memory = 0および1

ときovercommit_memoryに設定されている01、オーバーコミットが有効になり、プログラムが実際に利用可能であるよりも多くのメモリを割り当てることが許可されています。

ただし、プログラムが割り当てられたメモリを使用したいが、カーネルが実際にそれを満たすのに十分なメモリがないことを発見した場合、いくらかのメモリを取り戻す必要があります。最初に、キャッシュのフラッシュなど、さまざまなメモリクリーンアップタスクを実行しようとしますが、これが十分でない場合、プロセスを終了します。この終了は、OOM-Killerによって実行されます。OOM-Killerはシステムを調べて、どのプログラムがどのメモリを使用しているのか、どのくらいの時間実行されているのか、誰がそれらを実行しているのか、そしてどのプログラムが殺されるかを決定する他の多くの要因を確認します。

プロセスが強制終了された後、使用していたメモリが解放され、メモリ不足状態を引き起こしたプログラムに必要なメモリが確保されます。

ただし、このモードでも、プログラムは割り当て要求を拒否できます。ときovercommit_memory0、カーネルは、それが割り当て要求を拒否し始める必要がある場合に最良の推測を取るしようとします。に設定されている1場合、要求をいつ拒否するかを決定するためにどの決定を使用するかわかりませんが、非常に大きな要求を拒否することができます。

OOM-Killerが関係しているかどうかは、の出力を見て、次のdmesgようなメッセージを見つけることで確認できます。

[11686.043641] Out of memory: Kill process 2603 (flasherav) score 761 or sacrifice child
[11686.043647] Killed process 2603 (flasherav) total-vm:1498536kB, anon-rss:721784kB, file-rss:4228kB

だから、両方の状況が私に起こったようです。
NeutronStar

@ジョシュア私は答えを更新しました。私は、ときにまだ割り当てエラーを取得することができます言及するのを忘れてovercommit_memory0または2に設定されている
パトリック・

OOMのキラー飼いならすためのリンクを投稿に編集することは価値があると思います。
0xC0000022L 14年

@ 0xC0000022Lありがとう、これは良い記事です(少し古くなっていますが)。OOMキラーを制御することについては何も言いたくありません。それは質問の一部ではないため(そして短い主題ではありません)、ここには他にもたくさんの質問があります。
パトリック14年

1
@mikeserv OOMキラーの動作は、それを制御することとは関係ないとは言いません。問題は、Linuxが彼のプログラムを殺すかどうかでした。Linuxがこれを実行しないようにするには、実際にLinuxが実行していることを確認する必要があります。そしてovercommit_memory=2、OOMキラーが有効になっていなくても、それを制御することは無関係です。ただし、OOMキラーであることが確認されると、それは別のテーマになり、ここで他の多くの質問と回答がカバーされます。
パトリック14年

16

真実は、あなたがそれをどのように見るかに関わらず-プロセスがシステムのメモリマネージャまたは他の何かのために詰まったかどうかに関係なく、それはまだバグです。メモリ内で処理しているすべてのデータはどうなりましたか?保存されているはずです。

一方でovercommit_memory=、LinuxのOOM管理を設定する最も一般的な方法がある、それはまたのようなプロセスごとに調整可能です。

echo [-+][n] >/proc/$pid/oom_adj

-17上記で使用すると、プロセスがメモリ不足管理から除外されます。おそらく一般的には素晴らしいアイデアではありませんが、バグハンティングを行う場合は価値があります-特にOOM コードかを知りたい場合。数値を正の値に増やすと、OOMイベントでプロセスが強制終了される可能性が高くなります。これにより、メモリ不足の状況でコードの復元力を強化し、必要に応じて正常に終了できるようになります。

次のように、プロセスごとにOOMハンドラーの現在の設定を確認できます。

cat /proc/$pid/oom_score 

そうでなければ、自殺に行くことができます:

sysctl vm.panic_on_oom=1
sysctl kernel.panic=X

これにより、メモリ不足の状態が発生した場合にコンピューターが再起動するように設定されます。Xカーネルパニックが発生してから再起動するまでにコンピューターを停止する秒数に上記の値を設定します。ワイルドに。

そして、何らかの理由であなたがそれを好きだと決めたら、それを永続的にします:

echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf

これは私が使用している共有クラスターです。他のユーザーは、同意なしに再起動することに感謝しないでしょう。
NeutronStar 14年

3
@ジョシュア-誰もがそれを望んでいることを私は非常に真剣に疑っています-それはアシモフのロボット工学の法則にさえ反します。一方、前述したように、プロセスごとにOOMを他の方法で構成することもできます。つまり、プロセスごとに定義された独自のルールセットに基づいて個人的にトリアージできます。そのようなことは、共有クラスターのシナリオで特に役立つように思えます。
mikeserv 14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.