10
votes

Comment pouvez-vous explorer le tas géré dans une application .NET pour identifier les optimisations de mémoire possibles?

Nous avons une application .NET que nos clients considèrent trop volumineux pour le déploiement de masse et que nous aimerions comprendre ce qui contribue à notre empreinte mémoire et est-il possible de faire de mieux sans abandonner complètement .NET et WPF.

Nous sommes intéressés à améliorer la taille totale et l'ensemble de travail privé (PWS). Dans cette question, je veux juste regarder les PWS. VMMAP signale généralement une PWS de 105 Mo. De cette image de 11 Mo est image, 31 Mo est un tas, 52 Mo est géré en tas, 7 Mo est des données privées et le reste est la pile, la table de page, etc.

Le plus grand prix ici est le tas géré. Nous pouvons prendre en compte environ 8 Mo de la masse mignon directement dans notre propre code, c'est-à-dire des objets et des fenêtres que nous créons et gérons. Le reste est présumé des objets .NET créés par les éléments du cadre que nous utilisons.

Ce que nous aimerions faire est d'identifier quel élément du cadre du cadre pour quelle partie de cette utilisation et potentiellement réactive notre système pour éviter leur utilisation dans la mesure du possible. Quelqu'un peut-il suggérer comment cette enquête peut être faite?

Clarification supplémentaire:

J'ai utilisé un certain nombre d'outils à ce jour, y compris les excellents profileurs de fourmis et le windbg avec SOS, et ils me permettent de voir les objets dans le tas géré, mais d'un intérêt réel ici n'est pas "quoi?", mais 'Pourquoi?' Idéalement, j'aimerais pouvoir dire: "Eh bien, 10 Mo d'objets ont été créés ici parce que nous utilisons WCF. Si nous écrivions notre propre transport maternel, nous pourrions économiser 8 Mo de cela avec un risque de qualité de qualité et y."

Faire un GCROT sur 300 000 objets et plus n'est pas possible.


0 commentaires

5 Réponses :


12
votes

Windbg pourrait être un outil utile pour vous. Il est livré avec le Outils de débogage pour Windows .

Une fois votre application Est en cours d'exécution, vous pouvez attacher WINDBG et explorer le tas géré. (Ou vous pouvez prendre une mémoire de mémoire et l'explorer hors ligne). Il sera capable de vous dire très vite que les types d'objets consomment les plus grandes quantités de mémoire.

Vous devrez d'abord charger le SOS extension qui permet le débogage des applications gérées: xxx

alors vous pouvez utiliser ! Dumpheap Pour obtenir des informations sur les tas, le commutateur -Stat donne des informations globales de tas sur quels types sont alloués: xxx

le -Type Paramètre donne des informations spécifiques sur des instances allouées du type spécifié: xxx

Il y a un tas d'autres commandes que vous pourriez trouver utiles comme:

  • ! gCroot - Pour suivre un objet alloué sauvegarder, il est root pour trouver pourquoi il est en mémoire.
  • ! Dumpobj - Pour jeter un objet spécifique afin que vous puissiez voir son contenu.
  • ! eeHeap - donner des statistiques de tas générales.

    msdn a un Liste complète des commandes SOS et leurs commutateurs.

    WINDBG est un outil assez complexe, mais il y a beaucoup de tutoriels et de guides en ligne si vous recherchez pour vous aider à démarrer. Sinon, je peux recommander le livre Débogage Microsoft. NET 2.0 Demandes par John Robbins qui passe de bons détails dans les capacités de débogage .NET de WINDBG et SOS.

    Vous pouvez charger l'extension SOS dans Visual Studio à la place de l'entrée dans l'immédiat Fenêtre, vous devriez peut-être utiliser les commandes SOS directement dans la fenêtre VS immédiate: xxx

    Vous pouvez également trouver le CLR Profiler et ceci Guide d'utilisation utile.


6 commentaires

J'utilise Windbg, mais j'ai du mal à attacher les objets dans le tas aux éléments-cadres qui les possèdent. Des conseils à ce sujet?


Une combinaison de! GCROT et! Dumpobj fait généralement le travail pour moi. Si tout votre code est dans un espace de noms commun, vous ne pouvez pas simplement faire quelque chose comme! Dumpheap -Stat -Type YourCompaniesNamesPace. Cela vous donnera les plus grandes classes d'utilisation de la mémoire dans votre code et vous pouvez voir s'il y a quelque chose qui vaut la peine d'être choisis. Tous vos visites vont de Windbg sont des indices, vous devrez revenir en arrière pour attacher ces indices avec un comportement réel.


Merci, cela me donne une idée de savoir où commencer, je ne pense pas qu'il y ait trop de sauce dans notre propre espace de noms actuellement (nous avons traversé un cycle d'optimisation déjà), mais je peux le faire avec les références connues de notre projet. Je vais essayer cela et ajouter des détails supplémentaires.


J'ai vérifié tous les ensembles référencés externes (système.data, system.xml, etc.) en faisant! Dumpheap -stat -t -Type system.xml Cela nous a donné une liste de tous les objets de cet espace de noms. Ce n'est pas la photo entière car il existe évidemment des objets généraux .NET (principalement dans l'espace de noms système) qui existent à l'appui des assemblages vérifiés. C'est un bon départ dans ce que j'essaie de faire, surtout des assemblages qui sont à peine utilisés (petit nombre d'objets) peuvent être de bons candidats à la suppression de la taille de l'image (travail minimal requis pour mettre en œuvre la fonctionnalité fournie)


@Downward: Parlez-vous de la mémoire de la mémoire de tasse ou des assemblages chargés qui prennent la mémoire. C'est quelque chose de très différent. WINDBG vous indique que l'utilisation de la mémoire de tasse gérée, pas la quantité d'espace requise pour charger les assemblys tels que system.xml


@Simon: les deux :), mais essentiellement d'essayer de comprendre quelles assemblées (qui sont également chargées) créent les objets sur le tas géré, que je n'ai pas directement créé.



1
votes

Le profileur CLR affiche également la mémoire allouée par type dans le tas graphique.


0 commentaires

0
votes

Tout profileur de mémoire décent vous montrera ces informations. Vous ne voulez pas vraiment gâcher avec le libre PROFILER CLR , il ne vaut pas votre temps, obtenez un outil 3ème parti décent. Vous les trouverez mentionné dans ce fil .


2 commentaires

J'ai le profileur des fourmis et j'utilise Windbg, mais attacher les objets dans le tas dans des parties spécifiques du cadre se révèle difficile.


Je ne peux pas voir votre écran d'ici. Documez votre problème mieux, quels objets de quelles classes voyez-vous?



1
votes

J'utilise profileur de mémoire .NET . Ceci est également utilisé par certaines équipes Microsoft en interne comme indiqué par un podcast PDC.


0 commentaires

3
votes

Le nouvel outil est PERFVIEW qui peut afficher l'arborescence de référence et également différer


0 commentaires