私は350MBのRAMと2GBのスワップスペースを備えた仮想マシンでVagrantを介してFreeBSD 12を実行しています。
私が実行した場合:
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
予想通りに働きました。 5つのプロセスを開始し、それぞれ400MB(プロセスあたり2×200MB)を消費しました。
しかし、削除するとsleep 10
:
perl -e '$a="x"x200_000_000;sleep 1000' &
perl -e '$a="x"x200_000_000;sleep 1000' &
perl -e '$a="x"x200_000_000;sleep 1000' &
perl -e '$a="x"x200_000_000;sleep 1000' &
perl -e '$a="x"x200_000_000;sleep 1000' &
FreeBSDは2つの仕事を殺しました。
なぜ?
どうすれば回避できますか?
5つ以上実行する場合:
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
その後、メモリ不足のために最新のエントリが終了すると予想しました。しかし、FreeBSDはPerlタスクをランダムに選択して終了するようです。
次のスクリーンショットは次のとおりですtop
。
last pid: 3529; load averages: 1.45, 0.62, 0.34 up 0+00:17:14 21:49:30
29 processes: 5 running, 24 sleeping
CPU: 0.6% user, 0.0% nice, 34.5% system, 6.6% interrupt, 58.3% idle
Mem: 150M Active, 1080K Inact, 41M Laundry, 108M Wired, 39M Buf, 2256K Free
Swap: 2423M Total, 873M Used, 1550M Free, 36% Inuse, 33M In, 29M Out
PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
3521 vagrant 1 29 0 400M 53M RUN 1 0:03 25.98% perl
3525 vagrant 1 24 0 400M 52M RUN 1 0:03 4.11% perl
3527 vagrant 1 25 0 400M 53M RUN 0 0:02 4.09% perl
3523 vagrant 1 24 0 400M 52M RUN 1 0:03 3.53% perl
807 root 7 52 0 20M 1672K sigwai 1 0:00 0.07% VBoxService
答え1
長すぎる。
なぜ?
資源が枯渇すると、誰が生き残るかを保証することはできません。過度のメモリ使用量は目標を提供します。
どうすれば回避できますか?
メモリの割り当てには注意してください。必要以上に割り当てないでください。大量のメモリを急いで割り当てる必要がある場合は、「利用可能な」メモリを監視して、OOMがトリガされていないことを確認してください。
バラよりFreeBSDメモリーウィキそしてFreeBSDはどのようにメモリを割り当てますか?
気をつけてここに龍があります。
これは単なる推測です。あなたはそれに触れていないので、あなたが明らかに知っていることに言及します:
システムリソースが制限されています。 RAMはわずか350MBですが、作業にはスワップスペースが十分です。非常に小さな休止時間がある限り、ページ出力デーモンはダーティページの一部または全部を実行して交換する時間があります。遅滞なく試合が始まりました。
アクティブおよび非アクティブキューには、クリーンページとダーティページが含まれます。不足を軽減するためにメモリが回収されると、ページデーモンは非アクティブキューの先頭からクリーンなページを解放します。ダーティページは、まずスワップまたはファイルシステムでページングして消去する必要があります。これは多くのジョブなので、ページデーモンは遅延処理のためにそのジョブをランドリーキューに移動します。
——優秀記事から抜粋FreeBSDでスワップを見る
NUMAシステムには複数のページデーモンとランドリースレッドがある可能性があることに注目する価値があります。
あなたは彼らが順番に殺されると予想しています。しかし、システムはそのような保証を提供しません。これは極端なケースであり、システムは完全にマフィアです。「男は男がしなければならないことをしなければならない」。。背後には一種の「秩序」があるでしょう。
終了するプロセスを見つけるために、カーネルは実行可能な各プロセスのメモリ使用量を見積もり、使用量が最も多いプロセスを選択します。
ただし、プロセスは同じであるため役に立ちません。次に、プロセスが完全に順次実行されるのか、それとも別のシステムプロセスがランドリーリストのプロセスを一掃し、ページの順序を指定するのかについて詳しく説明します。したがって、OOMが発生した場合、システムは生き残ろうとしますが、決定論的な保証を提供しません。
プロセス優先順位(良いレベル)を尊重したいと主張したり、特定のメモリ優先順位を設定したりすることもできます。そんなことはない私のもの知識。 OOMからプロセスを保護できますが、これは次の目的で予約する必要があります。本物 本物 本物重要でよくテストされたシステムサービスです。
注意深く観察してください
問題が発生すると、コンソールログに記録されます。これより複雑な状況をデバッグする場合に役立ちます。
主に次のようなものを探しています:
pid . . ., was killed: failed to reclaim memory
pid . . ., was killed: a thread waited too long to allocate a page
pid . . ., was killed: out of swap space
kernel: swap_pager
これらのログファイルのいくつかを見たいと思うかもしれませんが、/var/log
最も興味深いファイルは次のとおりです。
dmesg | grep -e killed -e swap_pager
同調
OOMの動作を調整するには、次のsysctlsが役に立ちます。
vm.pageout_oom_seq: back-to-back calls to oom detector to start OOM
vm.panic_on_oom: panic on out of memory instead of killing the largest process
vm.pfault_oom_wait: Number of seconds to wait for free pages before retrying the page fault handler
vm.pfault_oom_attempts: Number of page allocation attempts in page fault handler before it triggers OOM handling
vm.v_pageout_free_min: Min pages reserved for kernel
vm.pageout_oom_seq: back-to-back calls to oom detector to start OOM
vm.pageout_lock_miss: vget() lock misses during pageout
vm.disable_swapspace_pageouts: Disallow swapout of dirty pages
vm.pageout_update_period: Maximum active LRU update period
たとえば、vm.pageout_oom_seq
デフォルトは12です。この値を下げると、OOMはpagedaemonの進行不足にさらに敏感になります。
してはいけないこと
問題を深く掘り下げると、いくつかの興味深い兆候が見つかります。あなたのケースは当然一つの例なので、あなたが正確に何を達成しようとしているのか私たちは知りません。
見たら参考(1)あなたは旗を見つけることができますP_SWAPPINGOUT
。実行している作業に応じて、自分のプロセスが実際に交換されていることを確認するために慎重に注意することができます。現実の世界では、割り当てる前に利用可能なメモリをチェックする方が良いでしょう。
これらのマークを見ると、あなたがそれを見ると不当な誘惑を受ける可能性がありますP_PROTECTED
。他の場所ではこれを madvise(MADV_PROTECT) とも呼ばれます。これはOOMから保護されるプロセスです。
するいいえそれを使用してください。
この値は、次のコマンドを使用してプロセスに対して簡単に設定できます。保護(1)
するいいえそれを使用してください。
rcサービスの場合は、${name}_oomprotect
rc.conf
変数をに設定して設定できます“YES”
。
するいいえそれを使用してください。
合理的なシステム設定と「十分」スペースを交換すると、システムが中断されます。
合理的な方法でメモリを割り当てるプロセスを作成した場合は、これについて考えることもできます。このプロセスが私にとって本当に重要で、メモリ割り当てを過度に使用したり、リークがある他の誤動作プロセスがあることがわかっている場合にのみこれを実行します。
良い記事があります。FreeBSDがPostgreSQLを終了するのを防ぐ(OOM Killer防止とも呼ばれる)しかし、私自身はそうしません。システムを上回ろうとすると、危険な場所に置かれます。 OOMは生存モードなので、世界の秩序ある崩壊に依存する内容を作成してはいけません。