11

私はいくつかの STL コンテナーを使用する予定のアプリケーションに取り組んでいます。メモリ消費量がしきい値に達すると、アプリケーションは特定の手順を実行します。そのためには、STL コンテナーが使用するメモリ量をほぼ正確に計算する必要があります。

vector<string> StringList
map<string, int> mapstring

これは私がメモリを見積もっている方法です:

のサイズについてStringListは、ベクトルのすべての要素をループし、文字列のサイズを追加し続けます。

string size = sizeof(string) + string.capacity()*sizeof(char)

そして最後にこれに追加しますsizeof(StringList);

mapstring のサイズについては、コンテナーのすべてのキーをループし、文字列のサイズを追加し続けてから、int のサイズを追加しmapstring.size()*sizeof(int)ます。そして最後にこれに追加しますsizeof(mapstring);

より良いアプローチは、独自のアロケーター クラスを指定し、その中のメモリ使用量を追跡することだと思いますが、それを書くのは簡単ではありません。この見積もりはよさそうですか?

4

2 に答える 2

11

std::vectorおよびの場合std::string、サイズではなく容量の方が適切な近似値になります。ノードベースのコンテナ(std::setなど)の場合、ノードの数(おおよそ要素の数)に各ノードのサイズを掛ける必要があります。ただし、これは、アロケータがノードに最適化されたプールアロケータを使用しない場合にのみ正確です。

ただし、実際に使用されているメモリの量を知りたい場合は、グローバルoperator newと を置き換えてoperator delete、実際の割り当てを追跡することをお勧めします。さらに正確なのは、とを置き換えることmallocですfree。正式にはこれは許可されていませんが、実際には、機能しない実装に遭遇したことはありません。一方、とを置き換える場合mallocfree、実際のメモリ管理を自分で実装する必要があります。andを置き換えるoperator newと、 and operator deleteを使用できるため、かなり簡単になります。mallocfree

各割り当てには一定のオーバーヘッドがあることにも注意してください。それぞれ10バイトの100000割り当ては、それぞれ100000バイトの10割り当てよりもかなり多くのメモリを消費します。

于 2012-08-07T08:02:09.193 に答える
11

通常、合計でstd::vector<element>3 つの機械語+ sizeof(element) *メモリが必要です。典型的な実装では、オーバーヘッドは、ベクトルの開始、終了、および現在のサイズへのポインターで構成されます。要素自体は連続したメモリに格納されます。通常、実際の要素数の最大 2 倍の余裕があります。capacity()capacity()

通常、合計でstd::map<element, int>約 2 マシン ワード+要素ごとに3 マシン ワード+ [ sizeof(element) + sizeof(int) ] * num_elements のメモリが必要です。一般的な実装では、オーバーヘッドは格納された要素へのポインターで構成されます。要素自体は、その親と 2 つの子へのポインターと共にバイナリ ツリーに格納されます。

これらの経験則では、文字列あたりの平均文字数と文字列の総数を知る必要があるだけで、合計メモリ消費量を知ることができます。

于 2012-08-07T07:50:43.460 に答える