Comment analyser la mémoire Windows ?

Savoir gérer la mémoire est une compétence clé dans la réussite d’une application et pourtant j’entends encore dire que cela n’est plus nécessaire avec l’arrivée des langages managés. Qu’on se le dise, ce constat est FAUX !
Surveiller la quantité de mémoire que votre processus consomme est vital, surtout si ce dernier est censé fonctionner sur un serveur. La moindre fuite peut mener à une utilisation totale de la mémoire (physique et virtuelle) après quelques jours, ce qui se traduit par un blocage de la machine comme dans l’exemple suivant avec Windows 8 :
Mais que fait le « Garbage Collector » ? Et bien je vous répondrai simplement qu’il fait son travail : créer des objets et supprimer ceux qui ne sont plus référencés, mais son travail n’est pas de “déréférencer” les objets qui n’ont plus d’utilité (managés ou non).
Mémoire Windows : Gestionnaire de tâches
Certes nous connaissons tous le « Gestionnaire de tâches » de Windows, qui permet de vérifier sommairement l’état de la mémoire d’un processus, cela donne un aperçu rapide de l’état de la machine.
Néanmoins en tant que développeur je vous le déconseille fortement pour deux raisons :
– Le manque de précision
– La définition du mot « mémoire » qui varie
En effet, les valeurs annoncées par le « Gestionnaire de tâches » manquent de précision car l’on ne sait pas de quel type de mémoire il s’agit ; de plus la définition de la mémoire varie d’une version de Windows à une autre…
Prenons pour exemple la dernière version en date (Windows 8), comme vous avez pu le remarquer dans ma capture précédente j’utilise une application console qui a tendance à réquisitionner beaucoup de mémoire. Voici le code que j’ai utilisé :
List<object> listArray = new List<object>(); try { while (true) { listArray.Add(new int[1000, 1000]); Thread.Sleep(100); } } catch (Exception ex) { Console.WriteLine(ex.Message); }
Evidemment ce code n’a pour seul but que d’utiliser le maximum de mémoire Windows autorisé pour un processus. Cela nous mène irrémédiablement vers le message suivant :
Et bien si l’on regarde l’état du processus via le fameux « Gestionnaire de tâches » on obtient un résultat plutôt surprenant :
A première vue nous sommes bien loin de la limitation imposée à un process 32bit (2Go). Afin de comprendre un peu mieux ce qu’il se passe il nous faut un outil plus précis, et pour cela nous allons nous tourner vers la suite SysInternals disponible gratuitement à l’adresse suivante : http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx
Pour commencer utilisons un gestionnaire de tâches que tout bon développeur devrait posséder : procexp (Process Explorer)
Cet outil peut être utilisé en complément ou en remplacement du gestionnaire de tâches natif.
Comme vous pouvez le constater cet outil offre bien plus de données sur l’état d’un processus. Vous pouvez d’ailleurs paramétrer les colonnes qui sont affichées en fonction de vos besoins. Mais l’un des points forts de cet outil par rapport au gestionnaire de tâches natif est de pouvoir afficher le détail d’un processus particulier :
Enfin nous pouvons avoir un état de la mémoire un peu plus détaillé. D’ailleurs nous retrouvons le chiffre annoncé auparavant par le gestionnaire de tâches Windows sous le libellé « WS Private » (5880K = 5,74M).
On constate que la mémoire virtuelle de notre processus a atteint la limite fixée par l’OS ce qui explique l’exception qui a été levée plus haut.
Certes nous pourrions en rester là, mais la suite SysInternals offre un outil encore plus puissant afin d’étudier la mémoire en profondeur : VMMap
Etudier la mémoire avec VMMap
VMMap permet d’analyser en détail la mémoire d’un processus. Vous avez la possibilité de l’utiliser en ligne de commande ou via l’interface graphique.
Reprenons notre exemple précédent afin de constater le problème. Lorsqu’on exécute VMMap, celui nous propose d’afficher l’état d’un processus en cours d’exécution ou de lancer un nouveau processus et de tracer son activité :
Je vais donc commencer par afficher l’état courant de mon application console après avoir levé une exception :
On constate que la mémoire du processus est entièrement décortiquée, on peut même connaitre le détail des 3 générations du Garbage Collector !
Dans cet exemple on voit très rapidement que la mémoire est principalement utilisée dans le Managed Heap et plus précisément dans le LOH.
Bien évidemment il est tout à fait possible de rafraichir les données à tout moment à l’aide de la touche « F5 »
A présent recommençons en lançant notre application à partir de VMMap afin d’en étudier l’évolution dans le temps :
L’interface reste inchangée, mais un bouton est désormais disponible : « Timeline… »
Lorsque l’on clique sur ce bouton on obtient une nouvelle fenêtre montrant l’évolution de la mémoire au court du temps :
Jusqu’ici il n’y a rien d’extraordinaire, mais l’intérêt de cette fenêtre est de pouvoir sélectionner un point de départ et un point d’arrivée afin de comparer les deux états :
Ce qui nous donne le résultat suivant :
Dans notre cas il n’y a que des ajouts (en vert), mais on pourrait très bien apercevoir des suppressions (en rouge).
Ce mode « Timeline » est également disponible en mode normal (Select Running Process), pour pouvoir y accéder vous devez disposer d’au moins 2 snapshots (à partir d’un refresh).
Vous avez désormais les clés en main pour commencer à travailler sur la mémoire, pour trouver plus d’information sur VMMap vous disposez d’un fichier d’aide fourni avec l’exécutable. Je n’ai abordé ici que VMMap mais il existe de nombreux outils pour analyser la mémoire (gratuit ou payant): Visual Studio, WinDBG, GlowCode, dotTrace… la liste est longue, mais l’avantage de VMMap est que cet outil est gratuit, simple d’utilisation et fourni par Microsoft désormais.
Vidéos sur la mémoire Windows
Si vous désirez en savoir plus sur le fonctionnement de la mémoire Windows, je vous recommande vivement de regarder les vidéos suivantes de Marc Russinovich (qui est à l’origine de la suite SysInternals):
http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/WCL405
http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/WCL406