@dunxdが言及しているドキュメントのセクション9.6「オーバーコミットとOOM」は、オーバーコミットを許可する危険性について特に図解されています。しかし、80
私にとっても面白そうだったので、いくつかのテストを行いました。
私が見つけたのは、これovercommit_ratio
がすべてのプロセスで利用可能なRAMの合計に影響するということです。ルートプロセスは、通常のユーザープロセスとは異なる方法で扱われるようには見えません。
比率を100
以下に設定すると、からの戻り値malloc/sbrk
が信頼できる古典的なセマンティクスが提供されます。それよりも低い比率を設定する100
と、キャッシュなどの非プロセスアクティビティ用により多くのRAMを予約できる可能性があります。
だから、スワップとRAMの24ジブ、と自分のコンピュータ上で、9ジブ使用中、使用不可にtop
示します
Mem: 24683652k total, 9207532k used, 15476120k free, 19668k buffers
Swap: 0k total, 0k used, 0k free, 241804k cached
いくつかのovercommit_ratio
設定と、RAM消費者プログラムが(各ページに触れて)取得できるRAMの量を以下に示しますmalloc
。いずれの場合も、プログラムは失敗すると正常に終了しました。
50 ~680 MiB
60 ~2900 MiB
70 ~5200 MiB
100 ~12000 MiB
一度に複数のユーザーを実行しても、一部がrootユーザーであっても、一緒に消費される合計量は変わりませんでした。興味深いのは、最後の3+ GiB程度を消費できなかったことです。free
ずっとここに示されているものを下回りませんでした。
Mem: 24683652k total, 20968212k used, 3715440k free, 20828k buffers
多くのプログラマーはCでmallocの失敗をチェックするのがひどく、一部の一般的なコレクションライブラリはそれを完全に無視し、C ++や他のさまざまな言語も悪い。
私が見た架空のRAMの初期の実装のほとんどは、1つの大きなプロセス(たとえば、使用可能なメモリの51%以上)fork()
がexec()
何らかのサポートプログラム(通常ははるかに小さいもの)をサポートするために必要な非常に特殊なケースを処理するものでした。copy-on-writeセマンティクスを備えたOS fork()
ではが許可されますが、フォークされたプロセスが実際に多くのメモリページを変更しようとした場合は(ただし、各ページは最初の巨大なプロセスから独立した新しいページとしてインスタンス化される必要があります)殺されることになります。親プロセスは、より多くのメモリを割り当てる場合にのみ危険にさらされ、場合によっては他のプロセスが停止するのを少し待ってから続行することで、不足を処理できました。子プロセスは通常、それ自体を(通常はより小さい)プログラムに置き換えますexec()
そして、但し書きはありませんでした。
Linuxのオーバーコミットの概念は、fork()
単一のプロセスが大規模に全体的に割り当てられるようにするだけでなく、両方を発生させるための極端なアプローチです。OOMキラーに起因する死亡は、さらにプログラムに、非同期的に起こる行うハンドルのメモリ割り当ての責任を。私は個人的にはシステム全体のオーバーコミット全般、特にoom-killerが嫌いです。これは、ライブラリに感染するメモリ管理への悪魔のようなケアのアプローチを促進し、ライブラリを介してそれらを使用するすべてのアプリを促進します。
比率を100に設定することをお勧めします。また、スワップパーティションも同様に、通常は巨大なプロセスでしか使用されません。大部分のプロセスをOOMキラーの誤機能から保護します。これにより、ウェブサーバーがランダムに死ぬのを防ぎ、malloc
責任を持って処理するように書かれている場合は、自分自身を殺すことからも安全に保つ必要があります(ただし、後者には賭けないでください)。
それは私がこれを使用していることを意味します /etc/sysctl.d/10-no-overcommit.conf
vm.overcommit_memory = 2
vm.overcommit_ratio = 100