0

これは、Windows 7 の MSVC++ 2010 で行った簡単なテストです。

// A struct with sizeof(s) == 4, e.g 4 bytes
struct s
{
    int x;
};

// Allocate 1 million structs
s* test1 = new s[1000000];

// Memory usage show that the increase in memory is roughly 4 bytes * 1000000 - As expected
// NOW! If I run this:
for (int i = 0; i < 1000000; i++)
    new s();

// The memory usage is disproportionately large. When divided by 1000000, indicates 64 bytes per s!!!

これは一般的な知識ですか、それとも何か不足していますか? 以前は、必要に応じてその場でオブジェクトを作成していました。たとえば、メッシュ内のすべての三角形に対して new Triangle() など。

個々のインスタンスの動的メモリ割り当てには、実際に桁違いのオーバーヘッドがありますか?

乾杯

編集:

g++ を使用して、Windows XP で動作中の同じプログラムをコンパイルして実行しました。オーバーヘッドは、以前に見られた 64 バイトではなく、16 バイトになりました。とても興味深い。

4

4 に答える 4

3

必ずというわけではありませんが、オペレーティング システムは通常、ユーザーに代わって、都合のよいサイズのチャンクでメモリを予約します。あなたのシステムでは、リクエストごとに 64 バイトの倍数が得られると思います。

結局のところ、メモリ割り当ての追跡に関連するオーバーヘッドがあり、非常に少量を予約する価値はありません。

于 2010-07-19T01:18:58.133 に答える
1

malloc実装を確認する必要があります。おそらくこれで問題が解決するでしょう。

mallocただし、MSVC++がどこかで表示できるかどうかはわかりません。そうでない場合は、他の実装を見てください。おそらくある程度似ています。

malloc実装が簡単であるとは思わないでください。割り当てられた仮想ページで空き領域を検索するか、新しい仮想ページを割り当てる必要があります。そして、これを迅速に行う必要があります。できるだけ速く。また、マルチスレッド対応である必要があります。おそらく、あなたのmalloc実装には、あるページでどの 64 ビット チャンクが空いているかを保証する何らかのビットベクトルがあり、次の空きチャンクを取得するだけです。

于 2010-07-19T01:48:37.200 に答える
1

Is that for a debug build? Because in a debug build msvc will allocate "guards" around objects to see if you overwrite past your object boundary.

于 2010-07-19T01:16:48.420 に答える
1

通常、単一のメモリ割り当てにはオーバーヘッドがあります。これは私の知る限りでmallocはありnewますが、同じだと思います。

メモリ アリーナのセクションは、(たとえば) 30 バイトの割り当て用に切り分けられると、通常はヘッダー (たとえば、16 バイト、およびそのようなすべての数値は以下の例に過ぎず、異なる場合があります) を持ち、パディングされる場合があります。アリーナ管理を容易にするために、16 バイトの倍数にします。

ヘッダーは通常、セクションを使い終わったときに、セクションを空きメモリ プールに再統合できるようにするために重要です。

最小限のブロックのサイズに関する情報が含まれており、(アリーナの破損を検出するための) メモリ ガードも含まれている場合があります。

したがって、100 万個の構造体配列を割り当てると、ヘッダー用に余分な 16 バイト (400 万と 16 バイト) が使用されることがわかります。100 万個の個々の構造体を割り当てようとすると、それぞれの構造体にそのオーバーヘッドが発生します。

関連する質問hereに詳細を回答しました。おそらくセクションサイズを超えてアイテムの数を格納する必要があるため(適切なデストラクタ呼び出しのために)、C++にはさらに必要なヘッダー情報があると思いますが、それは私の側の仮定にすぎません。割り当てられたアイテムごとに何らかの会計情報が必要であるという事実には影響しません。

スペースが何に使用されているかを本当に知りたい場合は、MSVC ランタイム ソース コードを掘り下げる必要があります。

于 2010-07-19T01:25:17.727 に答える