¿Cómo depurar pérdidas de memoria cuando el instrumento Leaks no las muestra?

Resuelto Rasto asked hace 54 años • 2 respuestas

Tengo una aplicación de iOS escrita en Swift que está perdiendo memoria; en determinadas situaciones, algunos objetos deberían liberarse, pero no es así. Aprendí sobre el problema simplemente agregando deinitmensajes de depuración como este:

deinit {
    println("DEINIT: KeysProvider released")
}

Por lo tanto, el mensaje deinit debería estar presente en la consola después de tales eventos que deberían provocar la liberación del objeto. Sin embargo, para algunos de los objetos que deberían liberarse, falta el mensaje. Aún así, Leaks Developer Tool no muestra ninguna fuga. ¿Cómo soluciono tal situación?

Rasto avatar Jan 01 '70 08:01 Rasto
Aceptado

En Xcode 8, puede hacer clic en el botón "Depurar gráfico de memoria", botón de gráfico de memoria de depuraciónen la barra de herramientas de depuración (que se muestra en la parte inferior de la pantalla):

gráfico de memoria de depuración

Consulte Diagnóstico y resolución de errores de Apple en su aplicación en ejecución: visualizar y diagnosticar el aumento del uso de memoria .

Simplemente identifique el objeto en el panel izquierdo que cree que debería haberse desasignado y le mostrará el gráfico de objetos (que se muestra en el lienzo principal, arriba). Esto es muy útil para identificar rápidamente dónde se establecieron las fuertes referencias en el objeto en cuestión. Desde aquí, puede comenzar su investigación, diagnosticando por qué esas referencias fuertes no se resolvieron (por ejemplo, si el objeto en cuestión tiene una referencia fuerte de otra cosa que debería haber sido desasignada, mire también el gráfico de ese objeto y puede encontrar la problema (por ejemplo, ciclos de referencia fuertes, temporizadores repetidos, etc.).

Observe que en el panel derecho veo el árbol de llamadas. Lo obtuve activando la opción de registro "malloc stack" en la configuración del esquema:

pila malloc

De todos modos, una vez hecho esto, se puede hacer clic en la flecha junto a la llamada al método relevante que se muestra en el seguimiento de la pila en el panel derecho de la primera captura de pantalla de arriba, y se puede ver dónde se estableció originalmente esa fuerte referencia:

código


La técnica tradicional de Instrumentos (especialmente útil si usa versiones anteriores de Xcode) se describe a continuación, en mi respuesta original.


Sugeriría utilizar la herramienta "Asignaciones" de Instruments con la función "Recuentos de referencias de registros":

registrar recuentos de referencias

Luego puede ejecutar la aplicación en Instrumentos y luego buscar la clase que sabe que tiene fugas y profundizar haciendo clic en la flecha:

ingrese la descripción de la imagen aquí

Luego puede profundizar en los detalles y ver el seguimiento de la pila usando el panel "Detalles extendidos" a la derecha:

detalles extendidos

En ese panel de "Detalles extendidos", concéntrese en su código en negro en lugar de las llamadas al sistema en gris. De todos modos, desde el panel "Detalles extendidos", puedes profundizar en tu código fuente, directamente en Instrumentos::

tu codigo

Para obtener más información y demostraciones sobre el uso de instrumentos para localizar problemas de memoria, consulte:

  • Vídeo de la WWDC 2021 Detecta y diagnostica problemas de memoria
  • Vídeo de la WWDC 2019 Introducción a los instrumentos
  • Vídeo de la WWDC 2018 Análisis profundo de la memoria de iOS
  • Vídeo de la WWDC 2013 Cómo solucionar problemas de memoria
  • Vídeo de la WWDC 2012 Rendimiento de la aplicación iOS: Memoria
Rob avatar Jun 23 '2015 03:06 Rob

Utilice instrumentos para comprobar si hay fugas y pérdida de memoria debido a memoria retenida pero no perdida. Esta última es memoria no utilizada a la que todavía se apunta. Utilice Generación de marcas (Heapshot) en el instrumento Asignaciones en Instrumentos.

Para saber cómo utilizar Heapshot para encontrar pérdidas de memoria, consulte: blog de bbum

Básicamente, el método consiste en ejecutar la herramienta de asignación de instrumentos, tomar una instantánea, ejecutar una iteración de su código y tomar otra instantánea repitiendo 3 o 4 veces. Esto indicará la memoria que se asigna y no se libera durante las iteraciones.

Para calcular los resultados, divulgue para ver las asignaciones individuales.

Si necesita ver dónde se producen las retenciones, liberaciones y liberaciones automáticas de un objeto, utilice los instrumentos:

Ejecute en instrumentos, en Asignaciones, active "Registrar recuentos de referencia" (para Xcode 5 e inferiores, debe detener la grabación para configurar la opción). Haga que la aplicación se ejecute, detenga la grabación, profundice y podrá ver dónde se produjeron todas las retenciones, liberaciones y liberaciones automáticas.

zaph avatar Jun 23 '2015 01:06 zaph