Linuxの楽観的なmalloc:新しいものはメモリから外れたときに常に投げますか?

StackOverflow https://stackoverflow.com/questions/1655650

質問

私はLinuxのメモリの条件から読んでいますが、Man Pagesからの次の段落は私に考えさせられました。

デフォルトでは、Linuxは楽観的なメモリ割り当て戦略に従います。これは、malloc()が非ヌルを返す場合、メモリが実際に利用可能であるという保証はないことを意味します。これは本当に悪いバグです。システムがメモリから外れていることが判明した場合、1つ以上のプロセスが悪名高いOOMキラーによって殺されます。 [...

オペレーターの新しい実装がある時点でMallocを呼び出すことになることを考えると、新しいものが実際にLinuxに投げられるという保証はありますか?ない場合、この明らかに検出不可能なエラーの状況をどのように処理しますか?

役に立ちましたか?

解決

場合によります; カーネルのオーバーコミット設定を構成できます vm.overcommit_memoryを使用します。

ハーブサッターは数年前にどのように議論しました この動作は実際にはC ++標準に不適合です:

「特にLinuxを含む一部のオペレーティングシステムでは、メモリの割り当ては常に成功します。完全な停止。要求されたメモリが実際に利用できない場合でも、割り当ては常に成功できますか?理由は、配分自体が単にメモリのリクエストを記録するためです。カバーの下では、(物理的または仮想的な)メモリは、メモリが実際に使用されるまで、実際のバッキングストアを使用して、実際に要求プロセスにコミットしていません。

「新しいものがオペレーティングシステムの施設を直接使用する場合、新しいものは常に成功しますが、BUF [100] = 'c'のような後の無実のコードは、標準のC ++の観点からスローまたは失敗または停止することができます。 C ++標準では、新品が十分なメモリをコミットできない場合は失敗する必要があり(これはそうではありません)、buf [100] = 'c'のようなコードが例外をスローしたり、失敗したりする必要があるため、不適合です。そうかもしれない)。"

他のヒント

純粋でシンプルなソフトウェアでそれを処理することはできません。

アプリケーションには、完全に有効なポインターが届きます。アクセスしようとすると、カーネルにページ障害が生成され、カーネルは物理ページを割り当てようとします。

しかし、ご覧のとおり、これはすべてカーネル内で起こりますが、アプリケーションはそれを見ることができません。重要なシステムの場合は、システム上のオーバーコミットを無効にすることができます。

マロックはまだnullを返すことができると思います。その理由は、利用可能なシステムメモリ(RAM +スワップ)とプロセスのアドレススペースの量に違いがあるためです。

たとえば、標準x86 LinuxでMallocから3GBのメモリを要求すると、ユーザースペースアプリに与えられるメモリの量が考えると不可能なため、確実にnullを返します。

私が間違っている場合は私を許してください、しかし、あなたが要求したすべてのバイトを持っていることを保証するのに十分であるために、割り当てられたメモリをゼロにしようとしないことは十分ではありませんか?または、最後のバイトに書き込むだけでさえ、メモリが本当にあなたのものでなければ例外を投げかけるでしょうか?

それが本当なら、あなたはただメモリの最後の(そして最初?)バイトに書き込み、それが正常に動作するかどうかを確認することができます。

はい、新しいものが最終的にスローするという保証が1つあります。オーバーコミットに関係なく、アドレススペースの量は限られています。したがって、メモリを割り当て続けると、遅かれ早かれ住所スペースがなくなり、新しいものが投げることを余儀なくされます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top