Speicherverbrauch durch STL-Container

8

Ich arbeite an einer Anwendung, in der ich einige STL-Container einsetzen möchte. Die Anwendung führt bestimmte Schritte aus, wenn der Speicherverbrauch einen Schwellenwert erreicht. Zu diesem Zweck muss eine genaue Berechnung durchgeführt werden, wie viel Speicherplatz STL-Container belegen.

%Vor%

So schätze ich den Speicher:

Um die Größe von StringList zu erreichen, überlappen Sie alle Elemente des Vektors und fügen Sie die String-Größen hinzu.

%Vor%

Fügen Sie dann endlich sizeof(StringList);

hinzu

Wenn Sie die Größe von Mapstring überschreiten, führen Sie eine Schleife über alle Schlüssel des Containers aus, fügen Sie die Stringgrößen hinzu und fügen Sie dann die Größen von int hinzu, die mapstring.size()*sizeof(int) ist. Dann füge endlich sizeof(mapstring);

hinzu

Ich denke, ein besserer Ansatz bestünde darin, die eigene Zuweisungsklasse anzugeben und die Speicherbelegung zu verfolgen, aber das Schreiben einer solchen könnte nicht-trivial sein. Sieht diese Schätzung gut aus?

    
Frank Q. 07.08.2012, 07:42
quelle

2 Antworten

11

Für std::vector und std::string würde die Kapazität und nicht die Größe ausreichen sei eine bessere Annäherung. Für knotenbasierte Container ( std::set , usw.), möchten Sie die Anzahl der Knoten (ungefähr die Anzahl der Knoten) multiplizieren Elemente) mal die Größe jedes Knotens. Dies ist jedoch nur dann richtig, wenn Der Zuordner verwendet keinen optimierten Poolzuordner für die Knoten.

Wenn Sie wirklich wissen möchten, wie viel Speicher verwendet wird, a Eine bessere Strategie wäre es, die globalen operator new und operator delete , und verfolgen Sie die tatsächlichen Zuordnungen. Sogar mehr genau wäre es, malloc und free zu ersetzen. Formal ist das nicht erlaubt, aber in der Praxis habe ich noch nie eine Implementierung wo gefunden es funktioniert nicht. Auf der anderen Seite, wenn Sie malloc und free ersetzen, Sie müssen die eigentliche Speicherverwaltung selbst implementieren. Wenn du Ersetzen Sie operator new und operator delete , Sie können malloc und verwenden free , was es ziemlich trivial macht.

Beachten Sie auch, dass jede Zuweisung einen festen Overhead hat. A 100000 Zuweisungen von je 10 Byte belegen deutlich mehr Speicher als 10 Zuweisungen von jeweils 100000 Bytes.

    
James Kanze 07.08.2012, 08:02
quelle
8

A std::vector<element> benötigt normalerweise 3 Maschinenwörter insgesamt + sizeof (Element) * capacity() des Speichers. Bei typischen Implementierungen besteht der Overhead aus Zeigern auf den Anfang, das Ende und die aktuelle Größe des Vektors. Die Elemente selbst sind in zusammenhängendem Speicher gespeichert. capacity() hat normalerweise Platz für die doppelte Anzahl an Elementen.

A std::map<element, int> benötigt normalerweise ungefähr 2 Maschinenwörter insgesamt + 3 Maschinenwörter pro Element + [sizeof (Element) + sizeof (int)] * num_elements des Speichers. Bei typischen Implementierungen besteht der Overhead aus Zeigern auf die gespeicherten Elemente. Die Elemente selbst werden in einem binären Baum mit Zeigern zu ihrem Eltern und zwei Kindern gespeichert.

Mit diesen Faustregeln müssen Sie nur die durchschnittliche Anzahl der Zeichen pro String und die Gesamtzahl der Strings kennen, um den Gesamtspeicherverbrauch zu kennen.

    
TemplateRex 07.08.2012 07:50
quelle