2

C のプログラムの最大ヒープ サイズは固定されていますか、それとも malloc し続けると、ある時点でオーバーフローし始めますか?

コード:

 while(connectionOK) //connectionOK is the connection with server which might be forever
 {
    if(userlookup_IDNotFound(userID))
     user_struct* newuser = malloc(getsize(user_struct));
     setupUserAccount(newuser);
 }

それが重要な場合、ubuntu / Linuxでgccを使用しています。getrlimit のようなものは知っていますが、ヒープサイズが得られるかどうかはわかりません。ただし、入力引数のオプションの 1 つにデフォルトのスタック サイズを指定します。また、プログラムのヒープ サイズを取得する方法についてここで提案されているように、valgrind はおそらく優れたツールですが、ヒープ オーバーフローが発生した場合はエラー メッセージを動的に出力したいと考えています。私の理解では、プロセス作成の開始時にOSによって割り当てられたプロセスアドレス空間(必要に応じて文字通りメモリ全体を使用することが許可されています)でしたが、要求後に物理メモリが動的に与えられるかどうかはわかりません追加メモリ用。

4

3 に答える 3

3

ヒープがオーバーフローすることはなく、特定の時点 (通常は return のとき) でメモリが不足するだけです。したがって、メモリ不足を検出するには、呼び出しのmalloc()戻りNULL値を確認するだけです。malloc()

if (newuser == NULL)
{
    printf("OOM\n");
    exit(1); /* exit if you want or can't handle being OOM */
}

malloc()内部的には OS からより多くのメモリを要求するため、動的に拡張されるため、不要になったページを OS に返し、必要なときにいつでもより多くのページを要求するため、実際には固定サイズではありません。

于 2013-02-04T22:49:35.980 に答える
2

技術的mallocには、ほとんどのシステムで割り当てられるのはメモリではなく、アドレス空間です。最新のシステムでは、数ペタバイトのアドレス空間を malloc で簡単に割り当てることができ、malloc はおそらく常に null 以外のポインターを返します。この背後にある理由は、ほとんどの OS が実際にメモリ割り当てを実行するのは、アドレス空間の一部がアクティブに変更された場合のみであるためです。そこに手を加えられていない限り、OS は、プロセスアドレス空間の特定の領域が将来の使用のために有効に予約されていることを記録するだけです。

この種の動作は「メモリーのオーバーコミット」と呼ばれ、Linux システムを保守する際に重要です。発生する可能性がある場合、しばらくの間、使用可能なメモリよりも多くのメモリが割り当てられ、一部のプログラムが実際にオーバーコミットされたメモリの一部に書き込みます。次に何が起こるかというと、いわゆる「メモリ不足キラー」(OOM キラー) が暴れ回り、最も適切と思われるプロセスを強制終了します。残念ながら、それは通常、どのような状況でも失いたくないプロセスです。データベースは、OOM キラーの主要な標的の 1 つであることが知られています。

このため、高可用性 Linux ボックスではメモリのオーバーコミットを切り替えることを強くお勧めします。メモリのオーバーコミットが無効になっている場合、アドレス空間の各要求はメモリによってサポートされる必要があります。その場合、要求が満たされない場合、malloc は実際には 0 を返します。

于 2013-02-04T23:11:10.480 に答える
1

システムがメモリを使い果たすと、ある時点で、malloc()が戻ります。NULL次に、それを逆参照しようとすると、プログラムは実行を中止します。

数回行うとどうなるか見てみましょうmalloc(SIZE_MAX):-)

于 2013-02-04T22:49:58.663 に答える