Mesurer l’utilisation de la mémoire dans Visual Studio (C#, Visual Basic, C++, F#)

Recherchez les fuites de mémoire et les utilisations inefficaces de la mémoire durant le débogage avec l’outil de diagnostic Utilisation de la mémoire intégré au débogueur. L’outil Utilisation de la mémoire vous permet de prendre un ou plusieurs instantanés du tas de mémoire managée et native afin de mieux comprendre l’impact de l’utilisation de la mémoire des types d’objets. Vous pouvez également analyser l’utilisation de la mémoire sans débogueur attaché ou en ciblant une application en cours d’exécution. Pour plus d’informations, consultez Exécution des outils de profilage avec ou sans débogueur. Pour plus d’informations sur le choix de l’outil d’analyse de mémoire le mieux adapté à vos besoins, consultez Choisir un outil d’analyse de la mémoire.

Bien que vous puissiez collecter des instantanés de la mémoire à tout moment dans l’outil Utilisation de la mémoire , vous pouvez utiliser le débogueur Visual Studio pour contrôler la façon dont votre application s’exécute lors de l’examen des problèmes de performances. La définition de points d’arrêt, l’exécution pas à pas, Interrompre tout et d’autres actions du débogueur peuvent vous aider à concentrer vos investigations en matière de performances sur les chemins du code qui sont les plus pertinents. Le fait d’effectuer ces actions pendant l’exécution de votre application peut éliminer le bruit du code qui ne vous intéresse pas et réduire considérablement le temps nécessaire pour diagnostiquer un problème.

Important

Les outils de diagnostic intégrés au débogueur sont pris en charge pour le développement .NET dans Visual Studio (y compris ASP.NET, ASP.NET Core), pour le développement natif/C++ et les applications en mode mixte (.NET et natives). Windows 8 et les versions ultérieures sont nécessaires pour exécuter les Outils de profilage avec le débogueur (fenêtre Outils de diagnostic).

Ce didacticiel présente les procédures suivantes :

  • Réaliser des instantanés de la mémoire
  • Analyser l’utilisation de la mémoire

Si Utilisation de la mémoire ne vous donne pas les données dont vous avez besoin, les autres outils de profilage dans le Profileur de performances fournissent des types d’informations différents qui peuvent vous être utiles. Dans de nombreux cas, le goulot d’étranglement des performances de votre application peut ne pas provenir de votre mémoire, mais du processeur, de l’interface utilisateur de rendu ou du temps de requête réseau.

Notes

Prise en charge des allocateurs personnalisés Le profileur de mémoire native fonctionne en collectant des données d’événements ETW d’allocation émises pendant l’exécution. Les allocateurs dans le CRT et le Kit de développement logiciel (SDK) Windows ont été annotés au niveau de la source afin que leurs données d’allocation puissent être capturées. Si vous écrivez vos propres allocateurs, toutes les fonctions qui retournent un pointeur vers la mémoire du tas nouvellement allouée peuvent être décorées avec __declspec(allocator), comme l’illustre cet exemple pour myMalloc :

__declspec(allocator) void* myMalloc(size_t size)

Collecter les données d’utilisation de la mémoire

  1. Ouvrez le projet que vous voulez déboguer dans Visual Studio, puis définissez un point d’arrêt dans votre application à l’endroit où vous voulez commencer à examiner l’utilisation de la mémoire.

    Si vous suspectez un problème de mémoire dans une zone spécifique, définissez le premier point d’arrêt avant que le problème de mémoire se produise.

    Conseil

    Comme il peut être difficile de capturer le profil de mémoire d’une opération qui vous intéresse si votre application alloue et libère fréquemment de la mémoire, définissez des points d’arrêt au début et à la fin de l’opération (ou bien exécutez pas à pas l’opération) pour trouver le point exact où la mémoire a été modifiée.

  2. Définissez un deuxième point d’arrêt à la fin de la fonction ou de la région de code que vous voulez analyser (ou après qu’un problème mémoire supposé se soit produit).

  3. La fenêtre Outils de diagnostic apparaît automatiquement, sauf si vous l’avez désactivée. Pour réafficher la fenêtre, cliquez sur Déboguer>Fenêtres>Afficher les outils de diagnostic.

  4. Choisissez Utilisation de la mémoire avec Sélectionner les outils dans la barre d’outils.

    Screenshot of Diagnostics Tools.

    Screenshot of Diagnostics Tools.

  5. Cliquez sur Déboguer / Démarrer le débogage (ou Démarrer dans la barre d’outils, ou F5).

    Lorsque l’application est chargée, la vue Résumé des outils de diagnostics s’affiche.

    Screenshot of Diagnostics Tools Summary Tab.

    Note

    Comme la collecte des données de la mémoire peut affecter les performances du débogage de vos applications natives ou en mode mixte, les instantanés de la mémoire sont désactivés par défaut. Pour activer les instantanés dans des applications natives ou en mode mixte, démarrez une session de débogage (touche de raccourci : F5). Quand la fenêtre Outils de diagnostic apparaît, choisissez l’onglet Utilisation de la mémoire, puis choisissez Profilage du tas.

    Screenshot of Enable snapshots.

    Arrêtez (touche de raccourci : Maj+F5) et redémarrez le débogage.

    Screenshot of Diagnostics Tools Summary Tab.

    Note

    Comme la collecte des données de la mémoire peut affecter les performances du débogage de vos applications natives ou en mode mixte, les instantanés de la mémoire sont désactivés par défaut. Pour activer les instantanés dans des applications natives ou en mode mixte, démarrez une session de débogage (touche de raccourci : F5). Quand la fenêtre Outils de diagnostic apparaît, choisissez l’onglet Utilisation de la mémoire, puis choisissez Profilage du tas.

    Screenshot of Enable snapshots.

    Arrêtez (touche de raccourci : Maj+F5) et redémarrez le débogage.

  6. Pour prendre un instantané au début de votre session de débogage, choisissez Prendre un instantané dans la barre d’outils récapitulative Utilisation de la mémoire. (Il peut être utile de définir un point d’arrêt ici aussi.)

    Screenshot of Take Snapshot button.

    Screenshot of Take Snapshot button.

    Astuce

    Pour créer une ligne de base pour les comparaisons de mémoire, envisagez de prendre un instantané au démarrage de votre session de débogage.

  7. Exécutez le scénario qui doit provoquer le premier point d’arrêt.

  8. Quand le débogueur est en pause sur le premier point d’arrêt, choisissez Prendre un instantané dans la barre d’outils récapitulative Utilisation de la mémoire.

  9. Appuyez sur F5 pour exécuter l’application jusqu’au deuxième point d’arrêt.

  10. Prenez maintenant un autre instantané.

    À ce stade, vous pouvez commencer à analyser les données.

    Si vous rencontrez des problèmes lors de la collecte ou de l’affichage des données, consultez Résoudre les erreurs de profilage et corriger les problèmes.

Analyser l’utilisation de la mémoire

Les lignes du tableau récapitulatif d’utilisation de la mémoire listent les instantanés que vous avez pris pendant la session de débogage et fournissent des liens vers des vues plus détaillées.

Screenshot of Memory Usage table.

Screenshot of Memory Usage table.

Les noms des colonnes varient selon le mode de débogage que vous choisissez dans les propriétés du projet : .NET, natif ou mixte (.NET et natif).

  • Les colonnes Objets (Diff.) et Allocations (Diff.) montrent le nombre d’objets dans la mémoire .NET et dans la mémoire native au moment où l’instantané a été pris.

  • La colonne Taille du tas (Diff.) montre le nombre d’octets dans les tas .NET et natif.

Quand vous avez pris plusieurs instantanés, les cellules de la table de résumé contiennent la différence de valeur entre l’instantané d’une ligne et l’instantané précédent.

Pour analyser l’utilisation de la mémoire, cliquez sur un des liens qui ouvrent un rapport détaillé de l’utilisation de la mémoire :

  • Pour voir les détails de la différence entre l’instantané actif et l’instantané précédent, cliquez sur le lien Modification à gauche de la flèche (Memory Usage Increase). Une flèche rouge indique une augmentation de l’utilisation de la mémoire et une flèche verte indique une baisse.

Astuce

Pour aider à identifier les problèmes de mémoire plus rapidement, les rapports de comparaison sont triés selon les types d’objets dont le nombre total a le plus augmenté (cliquez sur le lien de modification dans la colonne Objets (Diff.)) ou qui ont le plus augmenté dans la taille de segment totale (cliquez sur le lien de modification dans la colonne Taille du tas (Diff.)).

  • Pour afficher les détails de l’instantané sélectionné, cliquez sur le lien de non-modification.

    Le rapport s’affiche dans une fenêtre distincte.

Rapports sur les types managés

Choisissez le lien actif d’une cellule Objets (Diff.) ou Allocations (Diff.) dans le tableau récapitulatif Utilisation de la mémoire.

Screenshot of managed type report.

Screenshot of managed type report.

Le volet du haut affiche le nombre et la taille des types de l’instantané, y compris la taille de tous les objets qui sont référencés par le type (Taille inclusive).

L’arborescence Chemins d’accès à la racine du volet du bas affiche les objets qui référencent le type sélectionné dans le volet du haut. Le récupérateur de mémoire .NET nettoie la mémoire pour un objet seulement quand le dernier type qui le référence a été publié.

L’arborescence Objets référencés affiche les références qui sont détenues par le type sélectionné dans le volet du haut.

Screenshot of Referenced Objects report.

L’arborescence Types référencés affiche les références qui sont détenues par le type sélectionné dans le volet du haut.

Screenshot of Referenced Objects report.

Pour afficher les instances d’un type sélectionné dans le volet supérieur, cliquez sur « Afficher les instances » en regard du type d’objet.

Screenshot of the Instances view in the Memory Usage tool.

Screenshot of the Instances view in the Memory Usage tool.

La vue Instances affiche les instances de l’objet sélectionné dans l’instantané dans le volet du haut. Les volets Chemins d’accès à la racine et Objets référencés affichent les objets qui référencent l’instance sélectionnée, ainsi que les types référencés par l’instance sélectionnée. Quand le débogueur est arrêté du point où l’instantané a été pris, vous pouvez pointer sur la cellule Valeur pour afficher les valeurs de l’objet dans une info-bulle.

Rapports sur les types natifs

Cliquez sur le lien actif d’une cellule Allocations (Diff.) ou Taille du tas (Diff.) dans le tableau récapitulatif Utilisation de la mémoire de la fenêtre Outils de diagnostic.

Screenshot of Native Type View.

Screenshot of Native Type View.

La vue Types affiche le nombre et la taille des types dans l’instantané.

  • Choisissez l’icône des instances (The instance icon in the Object Type column). d’un type sélectionné pour afficher des informations sur les objets du type sélectionné dans l’instantané.

    La vue Instances affiche chaque instance du type sélectionné. La sélection d’une instance affiche la pile des appels qui a entraîné la création de l’instance dans le volet Pile des appels d’allocation .

    Screenshot of the Instances view and Allocation Call Stack pane.

  • Choisissez la Vue Instances à côté d’un type sélectionné pour afficher des informations sur les objets du type sélectionné dans la capture instantanée.

    La vue Instances affiche chaque instance du type sélectionné. La sélection d’une instance affiche la pile des appels qui a entraîné la création de l’instance dans le volet Pile des appels d’allocation .

    Screenshot of the Instances view and Allocation Call Stack pane.

  • Choisissez Affichage des piles dans la liste Mode Affichage pour afficher la pile des allocations pour le type sélectionné.

    Screenshot of Stacks view.

  • Choisissez Piles si vous voulez afficher la pile des allocations pour le type sélectionné.

    Screenshot of Stacks view.

Aperçus sur l’utilisation de la mémoire

Pour la mémoire managée, l’outil Analyse de la mémoire fournit également plusieurs puissants insights automatiques intégrés. Sélectionnez l’onglet Insights dans les rapports de types managés. Celui-ci montre les insights automatiques applicables, tels que Chaînes dupliquées, Tableaux éparset Fuites de gestionnaire d’événements.

Screenshot of the insight view in the Memory Usage tool.

La section Chaînes dupliquées affiche la liste des chaînes qui sont allouées plusieurs fois sur le segment de mémoire. En outre, cette section montre le total de la mémoire gaspillée, c’est-à-dire le (nombre d’instances - 1) fois la taille de la chaîne.

La section Tableaux éparses montre les tableaux qui sont pour la plupart remplis de zéro élément, ce qui peut être inefficace en termes de performances et d’utilisation de la mémoire. L’outil d’analyse de la mémoire détecte automatiquement ces tableaux et vous montre la quantité de mémoire gaspillée en raison de ces valeurs nulles.

La section Fuites de gestionnaire d’événements, disponible dans Visual Studio 2022 version 17.9 Preview 1, montre les fuites de mémoire potentielles qui peuvent se produire lorsqu’un objet s’abonne à l’événement d’un autre objet. Si l’éditeur de l’événement survit à l’abonné, ce dernier reste actif, même s’il n’y a pas d’autres références à celui-ci. Cela peut entraîner des fuites de mémoire, où la mémoire inutilisée n’est pas correctement libérée, ce qui entraîne l’utilisation par l’application de plus et plus de mémoire au fil du temps.

Certains types sont connus pour avoir des champs qui peuvent être lus pour déterminer la taille de la mémoire native qu’ils contiennent. L’onglet Aperçus affiche de faux nœuds de mémoire native dans le graphique d’objets, qui sont conservés par leurs objets parents, de sorte que l’interface utilisateur les reconnaît et affiche leur taille et leur graphique de référence.

Screenshot of the native insight view in the Memory Usage tool.

Rapports sur les modifications (Différences)

  • Cliquez sur le lien Modification dans une cellule du tableau récapitulatif de l’onglet Utilisation de la mémoire dans la fenêtre Outils de diagnostic .

    Screenshot of Choose a change link in a cell.

    Screenshot of Choose a change link in a cell.

  • Choisissez un instantané dans la liste Comparer à d’un rapport sur la mémoire managée ou native.

    Screenshot of Choose a snapshot from the Compare To list.

    Screenshot of Choose a snapshot from the Compare with list.

Le rapport des modifications ajoute des colonnes (marquées par la mention (Diff)) au rapport de base, qui affichent la différence entre la valeur de l’instantané de base et celle de l’instantané comparé. Voici à quoi peut ressembler un rapport des différences de la vue des types natifs :

Screenshot of Native Types Diff View.

Screenshot of Native Types Diff View.

Blogs et vidéos

Analyser le processeur et la mémoire pendant le débogage

Blog Visual C++ : Profilage de la mémoire dans Visual C++ 2015

Étapes suivantes

Dans ce didacticiel, vous avez appris comment collecter et analyser les données d’utilisation de la mémoire. Si vous avez déjà terminé la visite guidée du profileur, vous pouvez consulter une approche générale de l’optimisation du code à l’aide des outils de profilage.

Dans ce tutoriel, vous avez appris à collecter et analyser les données d’utilisation de la mémoire pendant le débogage. Vous souhaiterez peut-être en savoir plus sur l’analyse de l’utilisation de la mémoire dans les builds de version à l’aide du Profileur de performances.