Esercitazione: Ricerca di una perdita di memoria (JavaScript)

In questo argomento viene descritto il processo di identificazione e correzione di un semplice problema di memoria tramite JavaScript Memory Analyzer. In questa esercitazione creeremo un'app che genera una matrice di dati di grandi dimensioni. Si prevede che l'app elimini i dati quando si passa a una nuova pagina.

Nota

JavaScript Memory Analyzer è disponibile per Windows 8 in Visual Studio 2012 Update 1.

Esecuzione dell'app di test di JavaScript Memory Analyzer

  1. In Visual Studio fai clic su File > Nuovo > Progetto.

  2. Fai clic su JavaScript nel riquadro sinistro, quindi su Applicazione di navigazione nel riquadro centrale.

  3. Nella casella Nome digita un nome, ad esempio JS_Mem_Tester, quindi fai clic su OK.

  4. In Esplora soluzioni apri il file home.html nella cartella pages\home e incolla questo codice tra i tag <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>
    
  5. Apri home.js e sostituisci tutto il codice con quello seguente:

    (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 ]; })();
    
  6. Premi F5 per avviare il debug. Verifica che venga visualizzata questa pagina:

    Schermata iniziale dell'app di test

  7. Torna a Visual Studio (ALT+TAB) e premi MAIUSC+F5 per arrestare il debug.

    Dopo aver verificato che l'app funziona, possiamo analizzare l'utilizzo della memoria.

Analisi dell'utilizzo della memoria

  1. Sulla barra degli strumenti Debug fai clic su Simulatore nell'elenco a discesa Avvia debug.

    Puoi anche fare clic su Computer locale o su Computer remoto in questo elenco. Se tuttavia usi il simulatore, puoi posizionarlo accanto a Visual Studio per semplificare il passaggio tra l'app in esecuzione e JavaScript Memory Analyzer. Per ulteriori informazioni, vedi Esecuzione di app di Windows Store da Visual Studio e Esecuzione di app di Windows Store in un computer remoto.

  2. Scegli Analisi memoria JavaScript dal menu Debug, quindi fai clic su Avvia progetto di avvio.

    In questa esercitazione si assocerà l'analizzatore di memoria al progetto di avvio. Per informazioni su altre opzioni, come l'associazione dell'analizzatore di memoria a un'app installata, vedi Analisi dei dati di utilizzo della memoria (JavaScript).

    Quando avvii l'analizzatore di memoria, potresti vedere un messaggio di Controllo dell'account utente che richiede l'autorizzazione a eseguire VsEtwCollector.exe. Fai clic su .

  3. Dall'app in esecuzione passa a Visual Studio (ALT+TAB).

    JavaScript Memory Analyzer mostra le informazioni nella scheda Hub diagnostica.

    Il grafico relativo alla memoria in questa visualizzazione di riepilogo mostra l'utilizzo della memoria del processo nel tempo. La visualizzazione include anche comandi come Crea snapshot heap. Uno snapshot fornisce informazioni dettagliate sull'utilizzo della memoria in un momento specifico. Per ulteriori informazioni, vedi Analisi dei dati di utilizzo della memoria (JavaScript).

  4. Fai clic su Crea snapshot heap.

  5. Passa all'app e fai clic sul pulsante di avvio.

    Quando scegli il pulsante di avvio, il codice in home.js genera una matrice di grandi dimensioni che verrà usata per scopi diagnostici.

  6. Passa a Visual Studio e fai di nuovo clic su Crea snapshot heap.

    L'illustrazione mostra i due snapshot nel riquadro inferiore della visualizzazione di riepilogo.

    Riepiloghi di snapshot

  7. Puoi confrontare gli snapshot. Lo Snapshot n. 2 mostra quanto segue:

    • Le dimensioni heap (testo blu, lato sinistro) sono aumentate notevolmente, a oltre 1 MB.

    • La differenza nelle dimensioni heap rispetto allo snapshot precedente (testo rosso, lato sinistro) è di oltre 400 KB.

    • Il numero di oggetti nell'heap (testo blu, lato destro) è aumentato di diverse centinaia (a oltre 3.900).

    • La differenza nel numero di oggetti nell'heap (testo rosso, lato destro) rispetto allo snapshot precedente è di oltre 300 oggetti.

  8. Nello Snapshot n. 2 fai clic sul testo rosso a sinistra che mostra un valore differenziale quale +404 KB.

    Verrà aperta una visualizzazione differenziale, denominata Snapshot n. 2 - Snapshot n. 1, nella visualizzazione Denominatori aperta per impostazione predefinita. La figura seguente mostra questa visualizzazione.

    Differenza tra snapshot nella visualizzazione Dominatori

    In questa visualizzazione puoi vedere un elenco di oggetti che conservano la memoria, a partire da quelli che ne conservano la maggiore quantità. Per impostazione predefinita, JavaScript Memory Analyzer filtra gli oggetti incorporati creati da Windows Runtime e dalla Libreria Windows per JavaScript, in modo da concentrare le informazioni sul codice correlato all'app.

    Come puoi vedere, l'oggetto data ha un valore Diff. dimensioni conservate di oltre 400 KB.

    Suggerimento

    Quando è difficile individuare un determinato oggetto o identificatore, in alcune visualizzazioni puoi digitare il nome dell'identificatore nella casella Filtro nomi per trovare e selezionare l'identificatore specifico.

  9. Nell'elenco di identificatori fai clic con il pulsante destro del mouse sull'identificatore data, quindi scegli Mostra in visualizzazione radice.

    Il valore selezionato comparirà nella visualizzazione Radici della visualizzazione differenziale Snapshot n. 2 - Snapshot n. 1. La visualizzazione Radici mostra il punto in cui si fa riferimento all'oggetto che stai controllando in relazione all'oggetto Global. Ciò può facilitare l'identificazione del punto in cui si verifica un problema di memoria. Ecco un'illustrazione parziale della visualizzazione Radici a questo punto. L'oggetto Global nella parte superiore dell'albero non è visibile.

    Differenza tra snapshot nella visualizzazione Radici

    Nelle visualizzazione Radici possiamo vedere che si fa riferimento alla variabile data mediante una funzione anonima chiamata dalla funzione ready della home page e che questa ha origine in un elemento DIV contenente un oggetto winControl. Conoscendo l'app, è noto che l'oggetto di controllo si riferisce al pulsante di avvio dell'app.

  10. Passa all'app e fai clic sul pulsante Esplora.

    Il pulsante Esplora consente di passare a una nuova pagina. Per mantenere semplice questa app, ricarichiamo semplicemente la home page.

  11. Passa a Visual Studio e fai clic su Crea snapshot heap.

    In Snapshot n. 3 puoi vedere che le dimensioni heap e il numero di oggetti nell'heap non sono cambiati molto rispetto allo snapshot precedente. Ecco come appaiono gli snapshot:

    Snapshot dopo la pressione del pulsante Esplora

    Per questa esercitazione, i dati (la matrice) generati dall'app dopo che hai fatto clic sul pulsante di avvio vengono eliminati quando scegli Esplora per passare a una nuova pagina o, in questo caso, per ricaricarla. I dati non vengono tuttavia eliminati, quindi si dovrà correggere il problema.

  12. Fai clic sul pulsante Interrompi nella visualizzazione di riepilogo.

Correzione di un problema di memoria

  1. Nel file home.js rimuovi il codice per la gestione degli eventi del pulsante Esplora:

        function nButtonClicked(args) { WinJS.Navigation.navigate('/pages/home/home.html'); }
    

    Sostituiscilo con il codice seguente:

        function nButtonClicked(args) { data = null; WinJS.Navigation.navigate('/pages/home/home.html'); }
    
  2. Scegli Analisi memoria JavaScript dal menu Debug, quindi fai clic su Avvia progetto di avvio.

  3. Segui la stessa procedura descritta nella sezione precedente per acquisire tre snapshot. I passaggi sono riepilogati di seguito:

    1. Passa a Visual Studio e fai clic su Crea snapshot heap.

    2. Nell'app fai clic sul pulsante di avvio.

    3. Passa a Visual Studio e fai clic su Crea snapshot heap.

    4. Nell'app fai clic sul pulsante Esplora.

    5. Passa a Visual Studio e fai clic su Crea snapshot heap.

    Nello Snapshot n. 3 puoi vedere che le dimensioni heap sono simili a quelle dell'heap prima di fare clic sul pulsante di avvio e di generare dati. Ecco gli snapshot:

    Snapshot con problema di memoria risolto

  4. Nello Snapshot n. 3 fai clic sul testo blu che indica le dimensioni heap sul lato sinistro.

    Si aprirà la visualizzazione Dominatori per lo Snapshot n. 3. Questa è una visualizzazione dettagli dello Snapshot n. 3, non una visualizzazione differenziale.

  5. Nella casella Filtro nomi digita data.

    Questa volta l'heap non include alcuna variabile data. Il problema di memoria è stato quindi corretto.

Vedere anche

Concetti

Analisi dell'utilizzo della memoria nelle app di Windows Store (JavaScript)

Analisi dei dati di utilizzo della memoria (JavaScript)