4

仮想プログラムに似た私のアプリケーション:

for(;;) {
  for (i=0; i<1000; i++) {
    p[i] = malloc(random_number_between_1000_and_100000());
    p[i][0]=0;  // update
   }
  for (i=0; i<1000; i++) {
    free(p[i]);
  }
}

メモリリークはありませんが、私のシステムでは、メモリの消費量(上部、列VSS)が無制限に増加します(使用可能な物理メモリの300%など)。これは正常ですか?

更新-しばらくの間メモリを使用してから解放します。これは違いですか?

4

4 に答える 4

10

動作は正常です。引用man 3 malloc

バグ

デフォルトでは、Linuxは楽観的なメモリ割り当て戦略に従います。これは、malloc()がNULL以外を返す場合、メモリが実際に使用可能であるという保証がないことを意味します。これは本当に悪いバグです。システムのメモリが不足していることが判明した場合、悪名高いOOMキラーによって1つ以上のプロセスが強制終了されます。ランダムに選択されたプロセスを突然失うことが望ましくない状況でLinuxが使用され、さらにカーネルバージョンが十分に新しい場合は、次のようなコマンドを使用して、このオーバーコミット動作をオフに切り替えることができます。

       # echo 2 > /proc/sys/vm/overcommit_memory

カーネルのドキュメントディレクトリ、ファイルvm/overcommit-accountingおよびsysctl/vm.txtも参照してください。

Linuxカーネルのメモリを実際に予約するには、メモリをタッチ(読み取り/書き込み)する必要があります。

于 2009-11-26T14:39:27.037 に答える
1

OSは通常、すべてのページを「0」ページのコピーオンライトクローンとして割り当てます。これは、ゼロで埋められた固定ページです。ページから読み取ると、期待どおりに0が返されます。読むだけである限り、すべての参照は同じ物理メモリに送られます。値を書き込むと、「COW」が壊れて、実際の物理的なページフレームが割り当てられます。これは、メモリに書き込まない限り、仮想メモリのアドレススペースがなくなるか、ページテーブルが使用可能なすべてのメモリをいっぱいにするまで、メモリを割り当て続けることができることを意味します。

于 2009-11-26T16:10:21.940 に答える
1

追加してみてください

  sbrk(-1);

各ループの最後で、違いが生じるかどうかを確認します。

free()はメモリの割り当てを解除するだけですが、OSに戻すことはありません。

于 2009-11-26T15:00:05.613 に答える
0

割り当てられたチャンクに触れない限り、システムは実際にそれらを割り当てません。
ただし、アドレス指定可能なスペースが不足する可能性があります。これは、OSがプロセスに課す制限であり、必ずしもシステムポインタタイプでアドレス指定できる最大値ではありません。

于 2009-11-26T14:40:36.257 に答える