Linux で発生する可能性のあるメモリ不足の状態は 2 つあります。遭遇するものは sysctl vm.overcommit_memory
の値によって異なります (/proc/sys/vm/overcommit_memory
)
序章:
カーネルは、いわゆる「メモリ オーバーコミット」を実行できます。これは、カーネルがシステムに実際に存在するよりも多くのメモリをプログラムに割り当てる場合です。これは、割り当てられたすべてのメモリをプログラムが実際に使用しないことを期待して行われます。これは非常によくあることです。
overcommit_memory =2
overcommit_memory
のとき 2
に設定されています 、カーネルはオーバーコミットをまったく実行しません。代わりに、プログラムにメモリが割り当てられると、そのメモリへのアクセスが保証されます。割り当て要求を満たすのに十分な空きメモリがシステムにない場合、カーネルは要求に対して失敗を返します。この状況を適切に処理するかどうかは、プログラム次第です。実際に失敗したときに割り当てが成功したことを確認しないと、アプリケーションでセグメンテーション違反が発生することがよくあります。
segfault の場合、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
のとき 0
に設定されています または 1
、オーバーコミットが有効になっており、プログラムは実際に利用できるよりも多くのメモリを割り当てることができます。
ただし、プログラムが割り当てられたメモリを使用したいが、実際にはそれを満たすのに十分なメモリがないことをカーネルが発見した場合、メモリを取り戻す必要があります。最初に、さまざまなメモリクリーンアップタスクの実行を試みます。キャッシュをフラッシュしますが、これで十分でない場合はプロセスを終了します。この終了は、OOM-Killer によって実行されます。 OOM-Killer はシステムを調べて、どのプログラムがどのメモリを使用しているか、どのくらいの時間実行されているか、誰が実行しているか、その他多くの要因を調べて、どのプログラムが強制終了されるかを判断します。
プロセスが強制終了されると、プロセスが使用していたメモリが解放され、メモリ不足状態を引き起こしたプログラムが必要なメモリを確保できます。
ただし、このモードでも、プログラムは割り当て要求を拒否できます。overcommit_memory
の場合 0
です 、カーネルはいつ割り当て要求の拒否を開始すべきかについて最善の推測をしようとします。1
に設定されている場合 、リクエストをいつ拒否するかを決定するためにどのような決定を使用するかはわかりませんが、非常に大きなリクエストを拒否することができます.
dmesg
の出力を見ると、OOM-Killer が関与しているかどうかがわかります。 、次のようなメッセージを見つけます:
[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
真実は、どのように見ても、システムのメモリ マネージャーが原因でプロセスが停止したのか、他の何かが原因でプロセスが停止したのかに関係なく、まだ 停止しているということです。 バグ。メモリ内で処理していたすべてのデータはどうなったでしょうか?保存されているはずです。
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