Compartir a través de


Tutorial: Buscar una pérdida de memoria (JavaScript)

Este tema te guía por el proceso de identificar y corregir un problema simple de memoria con el analizador de memoria de JavaScript. En este tutorial, creamos una aplicación que genera una matriz grande de datos. Esperamos que la aplicación deseche los datos cuando naveguemos a una página nueva.

Nota

El analizador de memoria de JavaScript está disponible para Windows 8 en Visual Studio 2012 Update 1.

Ejecutar la aplicación de prueba del analizador de memoria de JavaScript

  1. En Visual Studio, haz clic en Archivo > Nuevo > Proyecto.

  2. Haz clic en JavaScript en el panel izquierdo y, a continuación, haz clic en Aplicación de navegación en el panel central.

  3. En el cuadro Nombre, escribe un nombre, como JS_Mem_Tester, y haz clic en Aceptar.

  4. En el Explorador de soluciones, en la carpeta pages\home, abre home.html y pega este código entre las etiquetas <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. Abre home.js y reemplaza todo el código con este código:

    (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. Presiona F5 para iniciar la depuración. Comprueba que aparece esta página:

    Pantalla de bienvenida de la aplicación de prueba

  7. Vuelve a Visual Studio (Alt+Tab) y presiona Mayús+F5 para detener la depuración.

    Ahora que hemos comprobado que la aplicación funciona, podemos examinar el uso de memoria.

Analizar el uso de memoria

  1. En la barra de herramientas Depurar, haz clic en Simulador en la lista desplegable Iniciar depuración.

    También puedes hacer clic en Equipo local o en Equipo remoto en esta lista. Si usas el simulador, puedes colocarlo junto a Visual Studio para facilitar el cambio entre la aplicación en ejecución y el analizador de memoria de JavaScript. Para obtener más información, consulta Ejecutar aplicaciones de la Tienda Windows desde Visual Studio y Ejecutar aplicaciones de la Tienda Windows en un equipo remoto.

  2. En el menú Depurar, apunta a Análisis de memoria de JavaScript y haz clic en Iniciar proyecto de inicio.

    En este tutorial, vamos a adjuntar el analizador de memoria al proyecto de inicio. Para obtener información sobre otras opciones, como adjuntar el analizador de memoria a una aplicación instalada, consulta Analizar datos de uso de memoria (JavaScript).

    Al iniciar el analizador de memoria, puede aparecer un Control de cuentas de usuario que solicite tu permiso para ejecutar VsEtwCollector.exe. Haz clic en .

  3. Desde la aplicación en ejecución, cambia a Visual Studio (Alt+Tab).

    El analizador de memoria de JavaScript muestra información en la pestaña Concentrador de diagnósticos.

    El gráfico de memoria de esta vista de resumen muestra el uso de memoria de proceso a lo largo del tiempo. La vista también proporciona comandos como Tomar instantánea de montón. Una instantánea proporciona información detallada sobre el uso de memoria en un momento determinado. Para obtener más información, consulta Analizar datos de uso de memoria (JavaScript).

  4. Haz clic en Tomar instantánea de montón.

  5. Cambia a la aplicación y haz clic en el botón Iniciar.

    El código de home.js genera una matriz grande cuando presionas Iniciar. Lo usaremos con fines de diagnóstico.

  6. Cambia a Visual Studio y vuelve a hacer clic en Tomar instantánea de montón.

    En esta ilustración se muestran las dos instantáneas en el panel inferior de la vista de resumen.

    Resúmenes de instantáneas

  7. Puedes comparar las instantáneas. En la instantánea 2 se muestra lo siguiente:

    • El tamaño del montón (texto azul, lado izquierdo) ha aumentado considerablemente, hasta más de 1 MB.

    • La diferencia en el tamaño del montón desde la instantánea anterior (texto rojo, lado izquierdo) es de más de 400 KB.

    • El número de objetos del montón (texto azul, lado derecho) ha aumentado en varios centenares (hasta más de 3.900).

    • La diferencia en el número de objetos del montón (texto rojo, lado derecho) desde la instantánea anterior es de más de 300 objetos.

  8. En la instantánea 2, haz clic en el texto rojo de la izquierda, que muestra un valor diferencial de +404 KB.

    Esto abre una vista diferencial, denominada Instantánea 2 - Instantánea 1, en la que se muestra la vista Dominadores de forma predeterminada. En la siguiente ilustración se muestra esta vista.

    Instantánea diferencial en la vista Dominadores

    En esta vista, aparece una lista de objetos que conservan la memoria, comenzando por los objetos que conservan más memoria. De forma predeterminada, el analizador de memoria de JavaScript filtra los objetos integrados creados por Windows en tiempo de ejecución y la biblioteca de Windows para JavaScript. Esto ayuda a centrar la información en el código relacionado con la aplicación.

    Puedes ver que el objeto data tiene un valor Diferencia de tamaño retenido de más de 400 KB.

    Sugerencia

    Cuando es difícil encontrar un objeto o un identificador deseado, en algunas vistas puedes escribir el nombre del identificador en el cuadro Filtro de nombres para buscar y seleccionar el identificador deseado.

  9. En la lista de identificadores, haz clic con el botón secundario en el identificador data y, a continuación, haz clic en Mostrar en vista raíz.

    El valor seleccionado aparece en la vista Raíces de la vista diferencial Instantánea 2 - Instantánea 1. La vista Raíces muestra dónde se hace referencia al objeto que estás inspeccionando en relación con el objeto Global. Esto puede ayudar a identificar dónde se está produciendo un problema de memoria. Aquí se muestra una ilustración parcial de la vista Raíces en este momento. (El objeto Global de la parte superior del árbol no está visible).

    Instantánea diferencial en la vista Raíces

    En las vista Raíces, podemos ver que una función anónima llamada por la función ready de la página principal hace referencia a la variable data, que tiene como raíz un elemento DIV que contiene un objeto winControl. Por nuestro conocimiento de la aplicación, sabemos que este objeto de control hace referencia al botón Iniciar de la aplicación.

  10. Cambia a la aplicación y haz clic en el botón Navegar.

    El botón Navegar navega a una página nueva. (Para que esta aplicación siga siendo simple, simplemente recargamos la página principal).

  11. Cambia a Visual Studio y haz clic en Tomar instantánea de montón.

    En la instantánea 3, puedes ver que el tamaño del montón y el número de objetos del montón no han cambiado mucho desde la instantánea anterior. Esta es la apariencia de las instantáneas:

    Instantánea después de presionar el botón Navegar

    Para este tutorial, esperamos que los datos (la matriz) generados por la aplicación después de presionar Iniciar se desechen al presionar Navegar para ir a una página nueva (o al recargar, en este caso). Sin embargo, los datos no se desechan, por lo que corregiremos ese problema.

  12. Haz clic en el botón Detener en la vista de resumen.

Corregir un problema de memoria

  1. En home.js, quita el código de control de eventos para el botón Navegar:

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

    Reemplázalo con este código:

        function nButtonClicked(args) { data = null; WinJS.Navigation.navigate('/pages/home/home.html'); }
    
  2. En el menú Depurar, apunta a Análisis de memoria de JavaScript y haz clic en Iniciar proyecto de inicio.

  3. Sigue el mismo procedimiento descrito en la sección anterior para tomar tres instantáneas. Aquí se resumen los pasos:

    1. Cambia a Visual Studio y haz clic en Tomar instantánea de montón.

    2. En la aplicación, haz clic en el botón Iniciar.

    3. Cambia a Visual Studio y haz clic en Tomar instantánea de montón.

    4. En la aplicación, haz clic en el botón Navegar.

    5. Cambia a Visual Studio y haz clic en Tomar instantánea de montón.

    En la instantánea 3 puedes ver que el tamaño del montón es similar al tamaño del montón antes de que presionaras Iniciar y se generaran datos. He aquí las instantáneas:

    Instantánea con el problema de memoria corregido

  4. En la instantánea 3, haz clic en el texto azul que muestra el tamaño del montón en el lado izquierdo.

    Esto abre la vista Dominadores para la instantánea 3. Esta es una vista de detalle de la instantánea 3, no una vista diferencial.

  5. En el cuadro Filtro de nombres, escribe data.

    Esta vez, no hay ninguna variable data presente en el montón. Por tanto, el problema de memoria se ha corregido.

Vea también

Conceptos

Analizar el uso de memoria en aplicaciones de la Tienda Windows (JavaScript)

Analizar datos de uso de memoria (JavaScript)