La consommation de mémoire par conteneurs STL
Je suis en train de travailler sur une application dans laquelle j'ai l'intention d'utiliser un couple de conteneurs STL. L'application permettra de prendre certaines mesures si la consommation de mémoire atteint un certain seuil. Pour ce but, j'ai besoin d'effectuer un près de calcul précis sur la quantité de mémoire utilisée par les conteneurs STL.
vector<string> StringList
map<string, int> mapstring
C'est la façon dont je suis l'estimation de la mémoire:
Pour la taille de l' StringList
, en boucle sur tous les éléments du vecteur et de continuer à ajouter de la chaîne de tailles.
string size = sizeof(string) + string.capacity()*sizeof(char)
Puis enfin ajouter à cette sizeof(StringList);
Pour la taille de l'mapstring, en boucle sur toutes les touches du conteneur et continuer à ajouter de la chaîne de tailles et ajoutez ensuite la taille des int qui est mapstring.size()*sizeof(int)
. Puis enfin ajouter à cette sizeof(mapstring);
Je suppose une meilleure approche serait la spécification propre allocateur de classe et de conserver la trace de l'utilisation de la mémoire à l'intérieur, mais l'écriture de l'un pourrait être non négligeable. Cette estimation de bien ?
std::map
élément doit contenir divers pointeurs, et les informations liées à la tenue de l'équilibre, ... outil Valgrind massif conserve la trace de l'allocation de tas, et peut être d'une certaine aide de profilage des programmes de l'utilisation de la mémoire.il a également dépend de l'implémentation STL vous utilisez. par exemple, STLPort ou gcc STL
"Je suppose que la meilleure approche serait la spécification propre allocateur de classe et de conserver la trace de l'utilisation de la mémoire à l'intérieur, mais l'écriture de l'un pourrait être non négligeable." -- C'est en effet la meilleure approche, beaucoup mieux que le deuxième deviner la STL mise en œuvre.
Ne pouvez-vous pas simplement demander au système d'exploitation la quantité de mémoire utilisée par le processus?
habituellement, une demande ne sera pas consommer toute la mémoire qu'il utilise.
OriginalL'auteur Frank Q. | 2012-08-07
Vous devez vous connecter pour publier un commentaire.
Pour
std::vector
etstd::string
, la capacité, plutôt que la taille, seraitêtre une meilleure approximation. Pour le nœud en fonction de conteneurs (
std::set
,etc.), vous voulez multiplier le nombre de nœuds (environ le nombre de
éléments) fois la taille de chaque nœud. Cette précision, cependant, si
l'allocateur de ne pas utiliser une optimisation de la piscine de l'allocateur pour les nœuds.
Si vous voulez vraiment savoir combien de mémoire est utilisé, cependant, un
la meilleure stratégie serait de remplacer le mondial
operator new
etoperator delete
, et de garder trace des allocations actuelles. Encore plusprécise serait de remplacer
malloc
etfree
. Officiellement, ce n'est pasautorisé, mais dans la pratique, je n'ai jamais rencontré une mise en œuvre où
il ne fonctionne pas. D'autre part, si vous remplacez
malloc
etfree
,vous devez mettre en œuvre la réelle gestion de la mémoire vous-même. Si vous
remplacer
operator new
etoperator delete
, vous pouvez utilisermalloc
etfree
, ce qui le rend assez trivial.Remarque aussi que chacun d'allocation a certains frais fixes. Un 100000
les allocations de 10 octets chacun va consommer beaucoup plus de mémoire que
10 allocations de 100000 octets chacun.
Cela dépend de ce que vous essayez de mesurer. Remplacement de nouveau vous donnera l'utilisation de la mémoire dynamique en C++ (mais pas dans toute les pièces que vous utilisez peut-être). C'est ce que je comprends par "consommation de mémoire". Il ne compte pas les trois pointeurs dans un
std::vector
qui est une variable locale sur la pile, mais il faudra compter tout de la mémoire utilisée par toutes les chaînes de caractères dans un vecteur (puisque la totalité de la mémoire pour le contenu d'un vecteur est allouée dynamiquement).OriginalL'auteur James Kanze
Un
std::vector<element>
prend généralement 3 mots au total + sizeof(element) *capacity()
de la mémoire. Pour les implémentations, les frais généraux sont constitués de pointeurs vers le début, la fin et la taille du vecteur. Les éléments eux-mêmes sont stockés dans la mémoire contiguë.capacity()
généralement a de la place pour jusqu'à deux fois le nombre réel d'éléments.Un
std::map<element, int>
prend en général environ 2 machine mots au total + 3 machine de mots par élément + [ sizeof(element) +sizeof(int) ] * num_elements de la mémoire. Pour les implémentations, les frais généraux se compose de pointeurs vers les éléments stockés. Les éléments eux-mêmes sont stockées dans un arbre binaire, avec des pointeurs vers ses parents et de deux enfants.Avec ces règles de base, tout ce que vous devez savoir, c'est le nombre moyen de caractères par chaîne et le nombre total de chaînes de connaître la consommation totale de mémoire.
std::vector
, vous devez utilisercapacity
, pas le nombre d'éléments. Et sistd::map
utilise un pool d'allocation (et beaucoup le font), alors il est probable que l'allocation de beaucoup plus de nœuds que il y a des éléments dans lamap
.Tnx, mis à jour pour le renforcement() remarque. Donc, pour
std::map
, est-il un non-intrusive façon (c'est à dire de ne pas l'enregistrement de l'allocateur) pour obtenir la consommation de mémoire?Si vous ne connaissez pas la mise en œuvre, il n'y a aucune manière; si l'allocateur utilise un pool de nœuds, il peut y avoir aucun moyen, période. La solution la plus simple est juste de remplacer mondiale
operator new
etoperator delete
avec ceux qui effectuent le suivi des allocations. (La valeur par défaut allocateurs sont nécessaires à l'utilisation de::operator new
d'acquérir la mémoire à allouer.)Aussi, votre commentaire concernant
capacity()
pouvez avoir de la place pour jusqu'à deux fois le nombre d'éléments n'est pas correct. Il n'y a pas de restriction sur la capacité, à l'exception qu'il développera par de multiples. Typique des multiples de 1,5 et 2, mais en plus grand (ou plus petit) sont certainement permis.J'ai à plusieurs reprises mentiond "typique de mise en œuvre", comme il n'y a pas de mandat de mise en œuvre de toute façon.
OriginalL'auteur TemplateRex