IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Allocation de mémoire


Sujet :

Langage C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Par défaut Allocation de mémoire
    Bonjour à tous,

    Je pose une question à des spécialistes de compilateur et/ou d'OS. J'ai des structures qui ont une taille bien définie par instance. J'ai fait des tests d'allocation de millions d'instances, et repéré l'augmentation de mémoire utilisée par rapport à ce que j'allouais théoriquement.

    En définitive, sous windows, pour un octet alloué, environ 40 octets sont utilisés. Sous ubuntu avec gnu gcc compiler, pour un octet alloué, environ 2.75 octets sont utilisés.

    Une explication possible serait que l'OS alloue une quantité de mémoire proportionnelle afin de conserver une main-mise sur l'application. Cependant, j'aimerais la confirmation ou l'infirmation de la part de spécialistes.

    Quelqu'un a-t-il des informations sur l'allocation réelle, dépendante de l'OS, ou du compilateur, en fonction de l'allocation théorique ? Une seconde question serait de savoir comment configurer les paramètres pour permettre de débrider les applications, et passer outre cette allocation supplémentaire.

    Dans l'attente de vous lire, cordialement.

  2. #2
    Invité
    Invité(e)
    Par défaut
    A priori, c'est davantage du ressort du compilateur (et des librairies gérant l'allocation mémoire) que de l'OS.

    En général, si tu utilises des allocations de bas niveau, sur des types de base, le "cout d'allocation" est très faible: quelques octets par objet alloué (et pas par octet utilisé).

    A priori, un truc du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int *tab=new int[10000];
    consommera la même quantité de "mémoire de gestion" que

    Cependant, il y a généralement une "taille minimale" des blocs de mémoire mis à disposition par la librairie. Si tu alloues des tailles inférieures, il y a de la perte. C'est peut être ce que tu observes.

    Si tu alloues beaucoup de tout petits objets (sur le tas, via malloc, new ou des choses similaires) il peut être intéressant d'allouer une 'réserve' au début, et de les allouer dans cette réserve (le C++ fournit des solutions clef en main pour ca, cherche dans tes livres des infos sur la surcharge de new).

    L'info à ce sujet doit se trouver dans les sources des librairies de ton compilateur (probablement dans les .h)


    Un autre problème intervient si tu alloues des structures (ou des classes). En général, les membres d'une structure sont alignés sur des débuts de mots ou de double mots. En 32 bits, chaque champ char d'une structure prend ainsi 4 octets... Ton compilateur a normalement une directive "pack" qui permet d'éviter cela.

    Enfin, si tu alloues dans des conteneurs (vector ou autres), sache que la STL leur donne une taille minimale par défaut (pour éviter les réallocations quand leur taille augmente). Celle ci doit figurer dans les sources de la STL. Si tes vector sont de taille 32 par défaut, mais que tu les utilises pour modéliser des objets de taille fixe de 4 éléments, ca peut vite faire assez mal.

    Francois

  3. #3
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Citation Envoyé par fcharton Voir le message
    Si tu alloues beaucoup de tout petits objets (sur le tas, via malloc, new ou des choses similaires) il peut être intéressant d'allouer une 'réserve' au début, et de les allouer dans cette réserve (le C++ fournit des solutions clef en main pour ca, cherche dans tes livres des infos sur la surcharge de new).

    L'info à ce sujet doit se trouver dans les sources des librairies de ton compilateur (probablement dans les .h)
    A ma connaissance il n'y a rien de standard dans le C++ au delà de l'operator new, la possibilité de le surcharger, std::allocator<> et les fonctions alloc(), malloc() et realloc().
    Le sujet revient souvent sur le forum sans jamais de concensus, à part celui d'admettre que la gestion de mémoire proposé par les compilateurs est largement suffisante.
    On parle parfois de garbage collector (pas trop recommandé, autant faire du java ou du C#), de small object allocator (celui de loki étant le plus célèbre, un autre est proposé dans boost) ou de memory pooler custom (c'est assez facile à faire).
    J'ai déjà demandé si quelqu'un s'était lancé dans l'écriture d'un allocator<>, sans succès. Le seul exemple trouvé et expliqué pas à pas est ici http://www.codeguru.com/cpp/cpp/cpp_...icle.php/c4079
    Perso je pense que l'allocator<> utilisé pour std::string et std::wstring mériterait d'être spécifique. Les strings sont utilisés partout dans les applications C++ (du moins il y a de fortes chances pour que ce soit le cas) et peuvent être la cause d'une grande fragmentation de la mémoire.

  4. #4
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Ben justement un custom allocator est ce dont parle fchartron (enfin il me semble).

  5. #5
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Citation Envoyé par GMany Voir le message
    J'ai des structures qui ont une taille bien définie par instance. J'ai fait des tests d'allocation de millions d'instances, et repéré l'augmentation de mémoire utilisée par rapport à ce que j'allouais théoriquement.
    Tu peux déjà vérifier qu'entre tes différents essais le sizeof() de tes structures (que l'on suppose POD) est constant indépendemment de la plateforme ou du compilateur (à noter qu'il y aura des différences entre 32 et 64 bits quand même). Si ce n'est pas le cas, il faut vérifier le paramétrage d'une option "pack" au niveau compilateur comme le disait fchartron.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par camboui Voir le message
    A ma connaissance il n'y a rien de standard dans le C++ au delà de l'operator new, la possibilité de le surcharger, std::allocator<> et les fonctions alloc(), malloc() et realloc().
    La surcharge de new, et l'utilisation du placement new, c'est assez standard, je crois (de mémoire, ca fait partie des exemples standard du bouquin de Stroustrup). C'est facile à implémenter, il y en a des exemples partout, et ca règle la plupart des problèmes qu'on rencontre en pratique. Dans le cas présent, ça devrait largement suffire. (En fait, je soupconne qu'un simple tableau initialisé au démarrage de l'appli suffirait probablement)

    Au delà, effectivement, on a des implémentations de poids-mouches (flyweight) dans Boost, et une description précise de la façon de le faire dans le bouquin d'Alexandrescu, mais ca me parait un peu énorme pour un besoin unique. Ce n'est vraiment utile, à mon avis, que quand on fait des allocations et des désallocations en très grand nombre, dans un ordre aléatoire, et sur des objets de taille très variable (mais souvent très petits).

    Alloc, malloc, realloc, c'est un peu bas niveau, non? Si on a new et ses surcharges...

    Pour les allocator<>, je suis resté sur un commentaire lu dans un livre (Meyers, je crois), selon lequel cela fait partie des bouts "mal finis" de la STL (comme auto_ptr, valarray, etc...). Et puis, c'est très spécifique aux conteneurs STL. Si tu alloues tes éléments en dehors de ces conteneurs (ou que ton conteneur, et éventuellement son allocateur maison, utilise les constructeurs par défaut de tes classes de base), le problème demeurera...

    @Goten: je pensais d'abord à la surcharge de new, mécanisme très puissant mis à notre disposition dans le langage "de base".

    Francois

Discussions similaires

  1. [debutant] : Allocation de mémoire dynamique
    Par sam.fet dans le forum Langage
    Réponses: 5
    Dernier message: 15/02/2006, 14h58
  2. Problème d'allocation de mémoire dans la pile
    Par prophet666 dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 19/01/2006, 02h22
  3. [Debutant]Allocation de mémoire
    Par gwendal84 dans le forum C
    Réponses: 6
    Dernier message: 07/12/2005, 19h04
  4. Double allocation de mémoire
    Par hunter001 dans le forum C++
    Réponses: 16
    Dernier message: 25/08/2005, 13h53
  5. pb d'allocation de mémoire
    Par shura dans le forum C
    Réponses: 7
    Dernier message: 17/04/2005, 21h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo