13

これは、G++4.1.2を使用するCentOS64ビット上のC++にあります。

システムのメモリ使用量をnギガバイトでロードするテストアプリケーションを作成しています。システム全体の負荷はSNMPなどで監視されるという考え方です。したがって、これは監視を実行する方法にすぎません。

しかし、私たちが見たのは、単に次のことをしているということです。

char* p = new char[1000000000];

topまたはfree-mに示されているように、使用されるメモリには影響しません。

メモリ割り当ては、メモリが次の場所に書き込まれると「実際」になるように見えます。

memcpy(p, 'a', 1000000000);   //shows an increase in mem usage of 1GB

ただし、すべてのメモリに書き込む必要があります。最初の要素に書き込むだけでは、使用されるメモリの増加は示されません。

p[0] = 'a';    //does not show an increase of 1GB.

これは正常ですか、メモリは実際に完全に割り当てられていますか?使用しているツール(topおよびfree -m)が誤った値を表示しているのか、コンパイラー、ランタイム、カーネルで何か巧妙なことが起こっているのかはわかりません。

この動作は、最適化がオフになっているデバッグビルドでも見られます。

new[]がすぐにメモリを割り当てたのは私の理解でした。C ++ランタイムは、後でアクセスされるまで、この実際の割り当てを遅らせますか?その場合、メモリが実際に割り当てられてからメモリにアクセスするまで、メモリ不足の例外を延期できますか?

それは私たちにとって問題ではありませんが、なぜこれがこのように起こっているのかを知ることは素晴らしいことです!

乾杯!

編集:

ベクターをどのように使用すべきか知りたくありません。これはOO/C ++ /現在のやり方などではありません。提案をするのではなく、なぜこれが現在のように行われているのかを知りたいだけです。それを試す別の方法について。

4

3 に答える 3

17

ライブラリがOSからメモリを割り当てる場合、OSはプロセスの仮想アドレス空間にアドレス範囲を予約するだけです。あなたがそれを使用するまで、OSが実際にこのメモリを提供する理由はありません-あなたが示したように。

たとえば/proc/self/maps、アドレス範囲を見るとわかります。トップのメモリ使用量を見ると、それはわかりません。まだ使用していません。

于 2011-03-17T15:45:57.900 に答える
8

オーバーコミットを探してください。Linuxはデフォルトで、アクセスされるまでメモリを予約しません。また、使用可能なメモリよりも多くのメモリが必要になった場合、エラーは発生しませんが、ランダムなプロセスが強制終了されます。この動作は。で制御できます/proc/sys/vm/*

IMO、オーバーコミットは、グローバルな設定ではなく、プロセスごとの設定である必要があります。また、デフォルトはオーバーコミットしないようにする必要があります。

于 2011-03-17T15:58:57.927 に答える
2

あなたの質問の後半について:

言語標準では、bad_allocのスローを遅らせることはできません。これは、ポインタを返すnew[]の代わりに発生する必要があります。後で起こることはありません!

一部のOSは、メモリ割り当てをオーバーコミットしようとし、後で失敗する可能性があります。これはC++言語標準に準拠していません。

于 2011-03-17T16:05:03.410 に答える