Didacticiel : Recherche d'une fuite de mémoire (JavaScript)
Cette rubrique vous guide dans le processus d'identification et de résolution d'un problème de mémoire simple à l'aide de l'analyseur de mémoire JavaScript. Dans ce didacticiel, nous allons créer une application qui génère un grand tableau de données. Nous attendons de l'application qu'elle supprime les données lorsque nous naviguons jusqu'à une nouvelle page.
Notes
L'analyseur de mémoire JavaScript est disponible pour Windows 8 dans Visual Studio 2012 Update 1.
Exécution de l'application test de l'analyseur de mémoire JavaScript
Dans Visual Studio, cliquez sur Fichier > Nouveau > Projet.
Dans le volet de gauche, cliquez sur JavaScript, puis sur Application de navigation dans le volet central.
Dans la zone Nom, tapez un nom, par exemple JS_Mem_Tester, puis cliquez sur OK.
Dans l'Explorateur de solutions, dans le dossier pages\accueil, ouvrez home.html et collez le code suivant entre les balises <body> :
<div class="fragment homepage"> <header aria-label="Header content" role="banner"> <button class="win-backbutton" aria-label="Back" disabled type="button"></button> <h1 class="titlearea win-type-ellipsis"> <span class="pagetitle">Welcome to JSMemTester!</span> </h1> </header> <section aria-label="Main content" role="main"> <p>Start generating data...</p> <button class="startButton" title="start" >Start</button> <p class="statusMsg1">""</p> <p>Navigate to page... (reload)</p> <button class="navButton" title="navigate" >Navigate</button> </section> </div>
Ouvrez home.js et remplacez l'ensemble du code par le code suivant :
(function () { "use strict"; var data; WinJS.UI.Pages.define("/pages/home/home.html", { // This function is called whenever a user navigates to this page. It // populates the page elements with the app's data. ready: function (element, options) { // TODO: Initialize the page here. var firstElem = document.querySelector('.startButton'); firstElem.addEventListener('click', sButtonClicked.bind(this)); var secondElem = document.querySelector('.navButton'); secondElem.addEventListener('click', nButtonClicked.bind(this)); }, generateData: function () { data = {}; var x = 0; var newData = "1"; for (var i = 0; i < 300; i++) { data[i] = "data" + newData; newData = newData + (100 * set[x]).toString(); if (i == 100) { x = 1; } if (i == 200) { x = 2; } } } }); function sButtonClicked(args) { this.generateData(); var elem = document.querySelector('.statusMsg1'); elem.textContent = "Done generating data (string array)."; } function nButtonClicked(args) { WinJS.Navigation.navigate('/pages/home/home.html'); } // Adding arbitrary values to sample data. var mod1 = 10; var mod2 = 100; var mod3 = 1000; var set = [mod1, mod2, mod3 ]; })();
Appuyez sur F5 pour démarrer le débogage. Vérifiez que cette page s'affiche :
Basculez à nouveau vers Visual Studio (Alt+Tab) et appuyez sur Maj + F5 pour arrêter le débogage.
Maintenant que nous avons vérifié que l'application fonctionne, nous pouvons examiner l'utilisation de la mémoire.
Analyse de l'utilisation de la mémoire
Dans la barre d'outils Déboguer, cliquez sur Simulateur dans la liste déroulante Démarrer le débogage.
Vous pouvez également cliquer sur Ordinateur local ou Ordinateur distant dans cette liste. Cependant, si vous utilisez le simulateur, vous pouvez le placer à côté de Visual Studio pour faciliter le basculement entre l'application en cours d'exécution et l'analyseur de mémoire JavaScript. Pour plus d'informations, consultez Exécution des applications du Windows Store à partir de Visual Studio et Exécution d'applications du Windows Store sur un ordinateur distant.
Dans le menu Déboguer, pointez vers Analyse de mémoire JavaScript, puis cliquez sur Lancer le projet de démarrage.
Dans ce didacticiel, nous allons attacher l'analyseur de mémoire au projet de démarrage. Pour plus d'informations sur les autres options, par exemple celle qui permet d'attacher l'analyseur de mémoire à une application installée, consultez Analyse des données d'utilisation de la mémoire (JavaScript).
Lorsque vous démarrez l'analyseur de mémoire, un message de contrôle de compte d'utilisateur peut demander votre autorisation pour exécuter VsEtwCollector.exe. Cliquez sur Oui.
À partir de l'application en cours d'exécution, basculez vers Visual Studio (Alt+Tab).
L'analyseur de mémoire JavaScript affiche des informations dans l'onglet Concentrateur de diagnostic.
Le graphique de mémoire dans ce mode Résumé illustre l'utilisation de la mémoire de processus au fil du temps. La vue fournit également des commandes telles que Prendre un instantané du tas. Un instantané fournit des informations détaillées sur l'utilisation de la mémoire à un moment donné. Pour plus d'informations, consultez Analyse des données d'utilisation de la mémoire (JavaScript).
Cliquez sur Prendre un instantané du tas.
Basculez vers l'application et cliquez sur le bouton Démarrer.
Lorsque vous appuyez sur Démarrer, le code dans home.js génère un grand tableau. Il sera utilisé à des fins de diagnostic.
Basculez vers Visual Studio et cliquez à nouveau sur Prendre un instantané du tas.
Cette illustration montre les deux instantanés dans le volet inférieur du mode Résumé.
Vous pouvez comparer les instantanés. L'instantané n° 2 affiche les informations suivantes :
La taille du tas (texte bleu, à gauche) a fortement augmenté et est désormais supérieure à 1 Mo.
La différence de la taille du tas par rapport à l'instantané précédent (texte rouge, à gauche) est supérieure à 400 Ko.
Le nombre d'objets sur le tas (texte bleu, à droite) a augmenté de plusieurs centaines (ce nombre est désormais supérieur à 3 900).
La différence du nombre d'objets sur le tas (texte rouge, à droite) par rapport à l'instantané précédent est supérieure à 300 objets.
Dans l'instantané n° 2, cliquez sur le texte rouge situé à gauche, qui indique une valeur différentielle d'environ +404 Ko.
Une vue comparée, Instantané n° 2 - Instantané n° 1, s'ouvre. La vue Dominators s'affiche par défaut. Voici une illustration.
Cette vue affiche une liste d'objets retenant la mémoire. Les premiers objets de la liste sont ceux qui retiennent le plus de mémoire. Par défaut, l'analyseur de mémoire JavaScript exclut les objets intégrés créés par Windows Runtime et par la bibliothèque Windows pour JavaScript. Cela permet de concentrer les informations sur le code lié à l'application.
Vous pouvez voir que la valeur Diff. taille de retenue de l'objet data est supérieure à 400 Ko.
Conseil
Lorsqu'il est difficile de trouver l'objet ou l'identificateur souhaité, certaines vues vous permettent de saisir le nom de l'identificateur dans la zone Filtre de nom, afin de rechercher et de sélectionner l'identificateur spécifique.
Dans la liste des identificateurs, cliquez avec le bouton droit sur l'identificateur data, puis cliquez sur Afficher en vue racine.
La valeur sélectionnée s'affiche dans la vue Racines de la vue comparée Instantané n° 2 - Instantané n° 1. La vue Racines indique où est référencé l'objet que vous examinez par rapport à l'objet Global. Cela peut vous aider à identifier l'endroit où se produit un problème de mémoire. Voici une illustration partielle de la vue Racines actuelle. (L'objet Global situé en haut de l'arborescence n'est pas visible.)
La vue Racines indique que la variable data est référencée par une fonction anonyme qui est appelée par la fonction ready de la page d'accueil, et qu'elle est enracinée sur un élément DIV qui contient un objet winControl. Notre connaissance de l'application nous permet de savoir que cet objet contrôle fait référence au bouton Démarrer de l'application.
Basculez vers l'application et cliquez sur le bouton Naviguer.
Le bouton Naviguer permet de naviguer vers une nouvelle page. (Pour ne pas rendre cette application complexe, nous rechargeons uniquement la page d'accueil.)
Basculez vers Visual Studio et cliquez sur Prendre un instantané du tas.
Dans l'instantané n° 3, vous pouvez voir que la taille du tas et le nombre d'objets sur le tas n'ont pas beaucoup évolué depuis l'instantané précédent. Voici à quoi ressemblent les instantanés :
Pour ce didacticiel, nous attendons que les données (le tableau) générées par l'application après avoir appuyé sur Démarrer soient supprimées lorsque vous appuyez sur Naviguer pour accéder à une page (ou recharger, dans le cas présent). Les données ne sont toutefois pas supprimées. Ce problème sera résolu.
Cliquez sur le bouton Arrêter dans le mode Résumé.
Résolution d'un problème de mémoire
Dans home.js, supprimez le code de gestion des événements pour le bouton Naviguer :
function nButtonClicked(args) { WinJS.Navigation.navigate('/pages/home/home.html'); }
Remplacez-le par le code suivant :
function nButtonClicked(args) { data = null; WinJS.Navigation.navigate('/pages/home/home.html'); }
Dans le menu Déboguer, pointez vers Analyse de mémoire JavaScript, puis cliquez sur Lancer le projet de démarrage.
Suivez la même procédure que celle décrite dans la section précédente pour prendre trois instantanés. Les étapes sont les suivantes :
Basculez vers Visual Studio et cliquez sur Prendre un instantané du tas.
Dans l'application, cliquez sur le bouton Démarrer.
Basculez vers Visual Studio et cliquez sur Prendre un instantané du tas.
Dans l'application, cliquez sur le bouton Naviguer.
Basculez vers Visual Studio et cliquez sur Prendre un instantané du tas.
Dans l'instantané n° 3, vous remarquez que la taille du tas est identique à celle du tas avant que vous ayez appuyé sur Démarrer et que les données aient été générées. Voici les instantanés :
Dans l'instantané n° 3, cliquez sur le texte bleu qui affiche la taille du tas, à gauche.
La vue Dominators s'ouvre pour l'instantané n° 3. Il s'agit d'une vue détaillée de l'instantané n° 3, et non d'une vue comparée.
Dans la zone Filtre de nom, tapez data.
Cette fois, aucune variable data n'est présente dans le tas. Le problème de mémoire est donc résolu !
Voir aussi
Concepts
Analyse de l'utilisation de la mémoire dans les applications du Windows Store (JavaScript)
Analyse des données d'utilisation de la mémoire (JavaScript)