0

インタビューで質問がありました。無限ループ内で大量のメモリを割り当てるとどうなりmalloc()ますか?free()

ヒープに十分なメモリがなく、ループを壊す必要がある場合に動作するはずの状態をチェックすることを考えNULLましたが、それは起こらず、プログラムは印刷によって異常終了しますkilled

なぜこれが起こっているのですか?またif、割り当てるメモリがない場合 (malloc() が失敗した場合)、なぜその部分が実行されないのですか? これは何の動作ですか?

私のコードは次のとおりです。

#include<stdio.h>
#include<stdlib.h>

int main(void) {
  int *px;

  while(1)
    {
     px = malloc(sizeof(int)*1024*1024);
     if (px == NULL)
       {
        printf("Heap Full .. Cannot allocate memory \n");
        break;
       }
     else
       printf("Allocated \t");
    }
  return 0;
}

編集: gcc - 4.5.2 (Linux-Ubuntu -11.04)

4

3 に答える 3

1

Linux で実行している場合は、最初のターミナルに注目してください。次のように表示されます。

OOM error - killing proc 1100

OOM はメモリ不足を意味します。

Linuxディストリビューションによっては、dmesgおよび/または/var/log/messagesおよび/またはでも表示されると思います。/var/log/system次のように grep できます。

grep -i oom /var/log/*

プログラムにメモリをゆっくりと取得させ、次の点に注意することができます。

watch free -m

利用可能なスワップが上下するのがわかります。ゼロに近づくと、Linux はプログラムを強制終了し、空きメモリの量が再び増加します。

これは、 httpfree -m : //www.linuxatemyram.com/の出力を解釈するための優れたリンクです。


この動作は、init または「god」などの他の保護メカニズムで開始されたアプリで問題になる可能性があります。Linux がアプリを強制終了し、init または何かがアプリを再起動するループに入る可能性があります。必要なメモリの量が使用可能な RAM よりもはるかに大きい場合、メモリ ページをディスクにスワップすることによって速度が低下する可能性があります。

場合によっては、Linux は問題の原因となっているプログラムを強制終了せず、他のプロセスを強制終了することがあります。たとえば、init を強制終了すると、マシンが再起動します。

最悪の場合、プログラムまたはプロセスのグループが大量のメモリ (Ram で利用できるよりも多く) を要求し、繰り返しアクセスしようとします。Linuxにはそのメモリをすばやく配置できる場所がないため、Ramの一部のページをディスク(スワップパーティション)にスワップアウトし、アクセス中のページをディスクからロードして、プログラムが表示/編集できるようにする必要があります。

これは、ミリ秒ごとに何度も何度も発生します。ディスクは RAM よりも数千倍遅いため、この問題によってマシンが実質的に停止する可能性があります。

于 2012-12-17T20:11:00.103 に答える
1

しかし、それは起こらず、プログラムは kill を印刷して異常終了します。

心に留めておいてください、あなたは一人ではありません。この場合、Out Of Memory キラーによって強制終了されました。このキラーは、プロセスがシステムのメモリを占有していることを確認し、それを停止するための措置を講じました。

なぜこれが起こっているのですか? また、割り当てるメモリがない場合 (malloc() が失敗した場合) に if 部分が実行されないのはなぜですか? これは何の動作ですか?

まあ、ifチェックが実行されなかったと信じる理由はありません。のマニュアルページをチェックしてくださいmalloc()

デフォルトでは、Linux は楽観的なメモリ割り当て戦略に従います。これは、malloc() が非 NULL を返す場合、メモリが実際に使用可能であるという保証がないことを意味します。システムのメモリが不足していることが判明した場合、1 つまたは複数のプロセスが OOM キラーによって強制終了されます。

つまり、小切手でメモリ不足の状態から自分を「保護」したと思います。実際には、 a を取得した場合NULLにのみ意味し、それを延期しなかったでしょう。要求したメモリを実際に取得したかどうかに関しては何も意味しません。NULL

于 2012-12-17T20:18:00.970 に答える
1

動作は ulimits によって異なります。http://www.linuxhowtos.org/Tips%20and%20Tricks/ulimit.htmを参照してください。

メモリの使用に制限がある場合は、予期される NULL 戻り動作が表示されます。一方、制限されていない場合は、見た OOM リーパーが表示される場合があります。

于 2012-12-17T20:15:28.893 に答える