Linux がデフォルトでメモリをオーバーコミットするのはなぜですか?

Linux がデフォルトでメモリをオーバーコミットするのはなぜですか?

スーパーユーザーの質問に関連してhttps://superuser.com/questions/200387/linux-オーバーコミットメモリ私の質問は、デフォルトでオーバーコミットを許可するようにした理由は何だったのかということです。

2.5.30以降の値は次のとおりです: 0 (デフォルト): 以前と同様: どの程度のオーバーコミットメントが妥当かを推測します。

答え1

Linux (および Unix システム全体) でメモリをオーバーコミットする必要がある主な理由はfork()、呼び出しプロセスのアドレス空間を複製するシステム コールを実装する必要があるためです。

ほとんどの場合、このシステム コールの後には が続きexec()、その組み合わせにより、現在のプロセスの子として別のプログラムが生成され、その場合、重複したアドレス空間の大部分は使用されなくなります。

これを効率的に行うために、Linux はコピーオンライトを使用して、 を呼び出すアプリケーションのメモリが重複するのを回避しますfork()。その場合、 が呼び出された直後にページを破棄するため、すべてのページをコピーする必要がなくなりますexec()

しかし、 が呼び出された時点ではfork()、 が来るかどうかはわかりませんexec()。 これはワーカーの子を生成するために使用されており、親のアドレス空間を再利用することが望まれている可能性が十分にあります。 (この手法は、接続を処理するために事前にフォークされたワーカーを使用するデーモンでは非常に一般的でした。) その場合、メモリ要件のほとんどまたは少なくとも一部は、フォークされた子に対して存在します (親のメモリの 100% ではないかもしれませんが、その大部分であると想定できます)。

しかし、常にそのケースのためにメモリを予約するのは、fork()+exec()の場合、特に親が数ギガバイトのメモリを予約し、多くの子をフォークする長時間実行プロセスである場合は面倒です。オーバーコミットがなければ、親が使用する数ギガバイトの合計量と、フォークした子ごとに予約する必要があります。しかし、exec()その予約はすぐにフラッシュされるため、実際にはまったく(またはほとんど)使用されません。最終的には、そのようなワークロードには、大量のスワップ領域(予約に対処するために、そのほとんどは未使用になりますが、最悪の場合に備えて必要です)またはオーバーコミットのようなものが必要になります。

は、この例をよく表していますがfork()、Linux/Unix の他の API もオーバーコミットの必要性につながります。たとえば、malloc()が呼び出されると (または、より正確には、それを実装する syscall が呼び出されると)、プロセスによって「アクセス」されるまでメモリは実際には割り当てられません。そのため、非常に大きなギガバイトのブロックを割り当てて、それをまばらに使用し、実際に使用されるのは数メガバイトだけになるようにすることはまったく問題ありません。これらの API がそのように動作するということは、プログラムがそれらの特性を利用することを意味します。つまり、オーバーコミットがないと、プログラムが壊れる可能性が高くなります (これらの予約をバックアップして無駄にするメモリやスワップが本当にたくさんある場合を除きます)。

この問題に関する興味深い議論はfork()以下でご覧いただけます。Microsoft Researchの記事に関するこのLWNの投稿記事自体はもちろん興味深いものです。しかし、コメント欄ではすぐにオーバーコミットとその問題点について触れられているのがわかります。

記事の名前は道の分岐点

答え2

理由は、すべての人がメモリを購入できるほどのリソースを持っているわけではないためだと思います。そのような場合、すべてのアプリケーションが適切に実行される必要があり、少ないリソースでアプリケーションを実行するのに役立ちます。

関連情報