Outils WinRT – la suite

Bonjour,

Dans le premier article suite à la session TechDays, je vous ai présenté les points suivants :

  • La méthode pour déboguer les applications lors de l’activation (par contrat ou par custom protocol par exemple)
  • Le débogage de votre code lors du Suspend/Resume et le lancement de l’application après un Terminate

En parallèle, j’ai mentionné les outils

 

Voici la suite :-)

 

Débogage Mémoire – Profilage Mémoire JavaScript

Pour illustrer la fonctionnalité de profilage Mémoire de Visual Studio 2013, créons un projet tout a fait standard de type Split App en Javascript :

SplitApp  Projet DiagnosticsPictures

Il vous suffit ensuite d’utiliser des images avec une grande résolution :

Images

Et de modifier la fonction generateSampleData dans le fichier data.js pour utiliser ces images :

function generateSampleData() { var itemContent = "Quelque texte"; var itemDescription = "Item Description"; var groupDescription = "Group Description";

// These three strings encode placeholder images. You will want to set the // backgroundImage property in your real data to be URLs to images. var darkGray = "../images/TechDays01.png"; var lightGray = "../images/TechDays02.png"; var mediumGray = "../images/TechDays03.png";

...

Testons directement l’application en activant le profilage mémoire JavaScript avec le menu ANALYSE / PERFORMANCE AND DIAGNOSTICS / JAVASCRIPT MEMORY de Visual Studio 2013 :

PerformanceAndDiagnostics

JavaScriptMemory

L’application est donc lancée. Nous pouvons l’utiliser et à tout moment revenir sur Visual Studio pour en prendre une capture mémoire en cliquant sur le bouton TAKE HEAP SNAPSHOT :

TakeHeapSnapShot

Il est ainsi possible de suivre l’évolution de la consommation mémoire de l’application en fonction de son utilisation et de prendre plusieurs captures. Visual Studio vous permet de comparer ces captures et de vous indiquer

  • quels objets ont été créés
  • lesquels ont été libérés

Lorsque que vous le souhaitez, utilisez le bouton STOP pour arrêter le profilage.

Stop Memory

Nous pouvons donc visualiser les résultats dans un tableau :

Size

Comment se fait-il que mes éléments <img> fassent 31Mo chacun alors que les images sur disque font au maximum 2,8Mo ? En définitive, nous avons des fichiers compressés et la décompression par Windows pour l’affichage créé des images de 3840*2160 = 8 Millions de pixels !

La solution dans notre cas est de fournir des images dont la résolution est adaptée à celle de l’écran mais aussi fonction du DPI.

Voici deux liens pour vous aider :

En réduisant la résolution à 800*450, nous avons plus qu’1,4Mo par tag <img> à la place de 31Mo (Nous divisons la taille par 22) ! Merci le profileur JavaScript Memory de Visual Studio !

Taille des images

SnapShot Size

 

 

Débogage Mémoire – Comparaison de dumps avec Visual Studio

Regardons maintenant une application C# dont la consommation mémoire est, quelque peu, inquiétante. Pour s’en rendre compte, je vous invite à utiliser Process Explorer de SysInternals et de suivre les private Bytes (Mémoire réelle utilisée). Pour le processus correspondant à notre application, nous avons une courbe de ce type :

Private Bytes dans Process Explorer

Comment savoir qui consomme la mémoire et surtout pourquoi il ne la libère pas ?

Avant, à l’ancienne :-), je prenais 2-3 dumps de mémoire séparés par quelques secondes et les ouvrais dans WinDbg. Le but du jeu était d’essayer d’identifier les objets .NET qui étaient chargées et quels étaient leur root. C’est à dire l’objet gardant un pointeur sur eux et empêchant leur libération par le Garbage Collector.

Mais ca… C’était Avant…. Maintenant, nous prenons toujours des dumps mais nous pouvons utiliser Visual Studio !

 

Pour la prise de dumps, j’utilise ProcDump de SysInternals. Il vous faut juste repérer le PID du processus (dans Process Explorer par exemple) et utiliser en ligne de commande administrateur :

procdump -MA <<PID>> -o C:\Dumps\

Prenez, par exemple, deux dumps séparés par quelques secondes d’utilisation de l’application afin d’avoir une différence de mémoire et de pouvoir ainsi comparer. Dans le cas ci-dessous, j’ai un premier dumps de 286Mo et un second de 359Mo.

Dumps

Maintenant, ouvrons Visual Studio et glissons/déplacer le premier dumps à l’intérieur :

image

Visual Studio analyse le contenu du fichier et nous propose dans un tableau tous les objets .NET issues de notre code. Il est ainsi aussi facile de les visualiser que si nous travaillons avec un tableau Excel. Vous retrouvez donc vos structures, objets, collections d’autant plus qu’ils portent les noms que vous leur avez donné :

Liste des objets

Le plus intéressant dans le cas d’une fuite mémoire est de pouvoir comparer deux dumps :

Comparer les dumps

Le tableau s’en trouve modifié comme suivant. Il nous montre notamment les différences en préfixant les valeurs par un "+" ou "-". Je ne pense pas que l’on puisse faire plus simple !

Dans la capture ci-dessous, nous avons 6 objets de type SampleDataGroup de moins dans le premier dumps par rapport au second.

Différences des bjets .NET

Dans la partie basse de la fenêtre, nous avons l’objet root qui _SampleDataSource. Il s’agit de notre contexte de données de l’application. Il nous reste donc à travailler sur le code afin de savoir comment nous ajoutons les SampleDataGroup à l’ObservableCollection.

root

 

--

 

Pour être totalement complet, il nous manque les explications/étapes correspondant à l'analyse de dumps provenant du Store.

Stay tuned!

 

Sebastien.