Remplacement des fenêtres malloc (par exemple, tcmalloc) et liaison crt dynamique
un programme C++ qui utilise plusieurs DLLs et QT devrait être équipé d'un programme de remplacement malloc (comme tcmalloc ) pour les problèmes de performance qui peuvent être vérifiés pour être causés par Windows malloc. Avec linux, il n'y a pas de problème, mais avec windows, il y a plusieurs approches, et je ne trouve aucune d'entre elles attrayantes:
1. Mettre nouveau malloc en lib et assurez-vous de le relier d'abord (autre question)
cela a l'inconvénient, que par exemple strdup utilisera toujours le vieux malloc et un gratuit peut planter le programme .
2. Retirez malloc de la bibliothèque statique libcrt avec lib.exe (Chrome)
est testé / utilisé(?) pour chrome / chrome , mais a l'inconvénient qu'il fonctionne seulement avec la liaison statique le crt. La liaison statique a le problème si une bibliothèque de système est liée dynamiquement avec msvcrt il peut y avoir des inadéquats dans l'allocation de tas/deallocation . Si je le comprends bien, tcmalloc pourrait être lié dynamiquement de telle sorte qu'il y ait un tas commun pour tous les dlls compilés (ce qui est bien).
3. Patch crt-code source (firefox)
de Firefox jemalloc apparemment, les patches, les fenêtres de code source CRT et construit un nouveau crt. Ceci a encore une fois le problème de liaison statique/dynamique ci-dessus.
on pourrait penser à l'utiliser pour générer un MSVCRT dynamique, mais je pense que ce n'est pas possible, parce que la licence interdit de fournir un MSVCRT corrigé avec le même nom.
4. Réparation dynamique du tube cathodique chargé à l'exécution
certains allocateurs mémoire commerciaux peuvent faire une telle magie. tcmalloc peut le faire aussi, mais cela semble plutôt laid. Il y avait des problèmes, mais ils ont été résolus. Actuellement, avec tcmalloc, il ne fonctionne pas sous des fenêtres 64 bits.
y a-t-il de meilleures approches? Tous les commentaires?
4 réponses
Q: Un programme C++ qui est partagé à travers plusieurs dll doit:
a) remplacer malloc?
B) s'assurer que l'allocation et la De-allocation se passe dans le même module dll?
: La réponse correcte est B. Une application c++ conception qui intègre plusieurs Dll DOIT s'assurer qu'il existe un mécanisme pour s'assurer que les choses qui sont allouées sur le tas dans une dll, sont libres avais par la même module dll.
Pourquoi est-ce que vous diviseriez un programme c++ en plusieurs dlls de toute façon? Par programme C++, je veux dire que les objets et les types avec lesquels vous avez affaire sont des gabarits c++, des objets STL, des classes, etc. Vous ne pouvez pas passer des objets c++ à travers les limites dll sans beaucoup de conception très soigneuse et beaucoup de magie spécifique au compilateur, ou souffrir de la duplication massive de code objet dans les différents dlls, et en conséquence une application qui est extrêmement sensible à la version. Toute petite le changement à une définition de classe va forcer une reconstruction de tous les exe et dll, supprimant au moins un des principaux avantages d'une approche dll au développement des applications.
soit coller à une interface c droite entre app et dll, souffrir enfer, ou tout simplement compiler l'application c++ entière comme un exe.
c'est une affirmation audacieuse qu'un programme C++ "devrait être équipé d'un programme de remplacement malloc (comme tcmalloc) pour les problèmes de performance...."
"[In] 6 des 8 populaire de repères ... [applications de taille réelle] en remplacement du répartiteur personnalisé, dans lequel les gens avaient investi beaucoup de temps et d'argent, ... avec le système fourni muet allocateur [donné] de meilleures performances. ... Les allocateurs personnalisés les plus simples, mis au point pour très spécial les situations, sont les seuls qui peuvent fournir des gains."-- Andrei Alexandrescu
la plupart des allocateurs-systèmes sont aussi bons qu'un allocateur d'usage général peut l'être. Vous pouvez faire mieux seulement si vous avez un modèle d'allocation très spécifique.
généralement, de tels modèles spéciaux s'appliquent seulement à une partie du programme, dans ce cas, il est préférable d'appliquer la coutume allocateur à la portion spécifique qui peut bénéficier qu'il est de remplacer globalement l'allocateur.
C++ fournit quelques façons de remplacer sélectivement l'allocateur. Par exemple, vous pouvez fournir un allocator à un conteneur STL ou vous pouvez outrepasser new et delete sur une base de classe par classe. Les deux vous donnent un contrôle bien meilleur que n'importe quel hack qui remplace globalement l'allocateur.
noter également que le remplacement de malloc et free ne sera pas nécessairement changement de l'allocateur utilisé par les opérateurs new et delete. Bien que le nouvel opérateur mondial soit habituellement mis en œuvre à l'aide de malloc, il n'est pas nécessaire qu'il le fasse. Remplacer malloc ne peut même affecter la plupart des affectations.
si vous utilisez C, il y a de fortes chances que vous puissiez envelopper ou remplacer les appels malloc et gratuits avec votre allocator personnalisé juste là où cela compte et laisser le reste du programme pour utiliser l'allocator par défaut. (Si ce n'est pas le cas, vous pourriez considérez certaines de refactoring.)
Système allocateurs ont des décennies de développement derrière eux. Ils sont stables et bien testé. Ils donnent de très bons résultats pour des cas généraux (en termes de vitesse brute, de tension de fil et de fragmentation). Ils ont des versions de débogage pour la détection des fuites et le soutien pour les outils de pistage. Certains améliorent même la sécurité de votre application en fournissant des défenses contre les vulnérabilités de dépassement de tampon tas. Les Chances sont, les bibliothèques que vous voulez utilisation ont été testé uniquement avec le système de l'allocateur.
la plupart des techniques utilisées pour remplacer le système de répartition perdent ces avantages. Dans certains cas, ils peuvent même augmenter la demande de mémoire (parce qu'ils ne peuvent pas être partagés avec le temps D'exécution DLL éventuellement utilisé par d'autres processus). Ils ont aussi tendance à être extrêmement fragiles face aux changements dans la version compilateur, la version runtime et même la version OS. À l'aide d'une version remaniée de l'exécution empêche vos utilisateurs d'obtenir les avantages des mises à jour d'exécution de la part du vendeur D'OS. Pourquoi renoncer à tout cela alors que vous pouvez conserver ces avantages en appliquant un allocateur personnalisé uniquement à la partie exceptionnelle du programme qui peut en bénéficier?
D'où vient votre prémisse "Un programme C++ qui utilise plusieurs DLLs et QT devrait être équipé d'un remplaçant malloc"?
sous Windows, si tous les dlls utilisent le MSVCRT partagé, alors il n'est pas nécessaire de remplacer malloc. Par défaut, Qt construit contre la dll MSVCRT partagée.
on rencontrera des problèmes s'ils:
1) mélange dlls qui utilisent la liaison statique vs En utilisant le vcrt partagé
2) et aussi mémoire libre qui n'a pas été attribuée d'où elle vient (c'est-à-dire mémoire libre dans une dll liée statiquement qui a été attribuée par le vcrt partagé ou vice versa).
notez que l'ajout de votre propre wrapper référencé autour d'une ressource peut aider à atténuer les problèmes associés aux ressources qui doivent être désallouées de manière particulière (par exemple, un wrapper qui dispose d'un type de Ressource via un rappel à la dll d'origine, un wrapper différent pour une ressource qui provient d'une autre dll, etc).
nedmalloc? notez également que smplayer utilise un patch spécial pour outrepasser malloc, qui peut être la direction dans laquelle vous vous dirigez.