Tutorial: usar la herramienta Instruments de Apple

Este artículo es una guía de uso de la herramienta Instruments de Apple para diagnosticar problemas de memoria en una aplicación iOS compilada con Xamarin. Muestra cómo iniciar Instruments, tomar instantáneas del montón y analizar el aumento de la memoria. También muestra cómo usar Instruments para mostrar e identificar las líneas de código exactas que provocan el problema de memoria.

En esta página se muestra cómo usar la herramienta Instruments de Xcode para diagnosticar un problema de memoria en una aplicación de iOS. En primer lugar, descargue el ejemplo MemoryDemo y abra la solución anterior en Visual Studio para Mac.

Diagnóstico de problemas de memoria

  1. En Visual Studio para Mac, inicie Instruments desde el elemento de menú Herramientas > Iniciar Instruments.

  2. Cargue la aplicación en el dispositivo eligiendo el elemento de menú Ejecutar > Cargar en el dispositivo.

  3. Elija la plantilla Asignaciones (icono naranja con cuadro blanco).

    Choose the Allocations template

  4. Seleccione la aplicación Memory Demo en la lista Choose a profiling template for: (Elegir una plantilla de generación de perfiles para:) en la parte superior de la ventana. Primero haga clic en el dispositivo iOS para expandir el menú que muestra las aplicaciones instaladas.

    Select the Memory Demo application

  5. Pulse el botón Elegir (extremo inferior derecho de la ventana) para iniciar Instruments. Esta plantilla mostrará dos elementos en el panel superior: Asignaciones y VM Tracker (Seguimiento de VM).

  6. Pulse el botón Grabar (círculo rojo del extremo superior izquierdo) de Instruments, lo que iniciará la aplicación.

  7. Seleccione la fila VM Tracker (Seguimiento de VM) del panel superior (ahora que la aplicación se está ejecutando, contiene dos secciones: Dirty y Resident Size). En el panel Inspector, elija la opción Show Display Settings (Mostrar configuración de pantalla) (el icono de engranaje) y luego active la casilla Automatic Snapshotting (Creación automática de instantáneas) del extremo inferior derecho de esta captura de pantalla:

    Choose the Show Display Settings option the gear icon then tick the Automatic Snapshotting checkbox

  8. Seleccione la fila Asignaciones del panel superior (ahora que la aplicación se está ejecutando indicará All Heap and Anonymous VM)

  9. En el panel Inspector, elija la opción Show Display Settings (Mostrar configuración de pantalla) (el icono de engranaje) y luego haga clic en el botón Mark Generation (Generación de marca) para establecer una línea de base. Aparecerá un pequeño indicador rojo en la escala de tiempo de la parte superior de la ventana

  10. Desplácese por la aplicación y vuelva a seleccionar Mark Generation (Generación de marca) (repita varias veces)

  11. Haga clic en el botón Detener.

  12. Expanda el nodo Generación con el mayor Crecimiento y ordene por Crecimiento (descendente).

  13. Vaya del panel Inspector a Show Extended Detail (Mostrar más detalles) (la "E"), que muestra el Seguimiento de la pila.

  14. Observe que el nodo <no objeto> muestra un aumento excesivo de la memoria. Haga clic en la flecha situada junto a este nodo para ver más detalles. Haga clic con el botón derecho en el seguimiento de la pila para agregar Ubicación de origen al panel:

    Add Source Location to the pane

  15. Ordene por Tamaño y muestre la vista Extended Detail (Más detalles):

    Sort by Size and display the Extended Detail view

  16. Haga clic en la entrada deseada en la pila de llamadas para ver el código relacionado:

    Viewing the related code

En este caso, se crea una nueva imagen y se almacena en una colección para cada celda; no se reutilizan las celdas de la vista de colección existentes.

Solución de problemas de memoria

Es posible solucionar estos problemas y volver a ejecutar la aplicación mediante Instruments.

Al declarar una sola instancia en el nivel de clase, se puede volver a usar la imagen y el objeto de celda de un grupo existente en lugar de crearlos cada vez, como se muestra a continuación:

public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
{
    // Dequeue a cell from the reuse pool
    var imageCell = (ImageCell)collectionView.DequeueReusableCell (cellId, indexPath);

    // Reuse the image declared at the class level
    imageCell.ImageView.Image = image;

    return imageCell;
}

Ahora, cuando se ejecuta la aplicación, se reduce enormemente el uso de memoria: el Crecimiento entre generaciones ahora se mide en k (kilobytes) en lugar de MB (megabytes), como se hacía antes de corregir el código:

Showing the app memory usage

El código mejorado está disponible en el ejemplo MemoryDemo de la solución posterior en Visual Studio para Mac.

El artículo Recolección de elementos no utilizados de Xamarin.iOS es una referencia útil para solucionar problemas de memoria con Xamarin.iOS.

Resumen

En este artículo se muestra cómo usar Instruments para diagnosticar problemas de memoria. En él se ha explicado cómo iniciar Instruments desde Visual Studio para Mac, cargar la plantilla de asignación de memoria y usar instantáneas para identificar problemas de memoria. Por último, se ha vuelto a examinar la aplicación para comprobar que se ha corregido el problema.