Middle+
¿Cómo determinar la presencia de una fuga de memoria al analizar un volcado?
sobes.tech AI
Respuesta de la IA
Para detectar fugas de memoria en un volcado (archivo HPROF), se utilizan herramientas que analizan el gráfico de objetos en el montón. Pasos principales:
-
Obtener el volcado de memoria:
- A través del Memory Profiler de Android Studio.
- Con el comando
adb shell dumpheap <nombre_paquete> /data/local/tmp/dump.hprof. - Con la llamada al sistema
Debug.dumpHprofData(filePath).
-
Analizar el volcado:
- Abrir el volcado en Android Studio: En Memory Profiler o mediante el menú "Archivo" -> "Abrir".
- Análisis de objetos: Ordenar objetos por tamaño (Shallow Size, Retained Size) y cantidad de instancias.
- Buscar objetos sospechosos: Busque clases que deberían ser destruidas (por ejemplo, Activity, Fragment, Contexts) pero tienen muchas instancias o un
Retained Sizesignificativo. - Estudiar la ruta al objeto (Cadena de Referencias): Seleccione un objeto sospechoso y trace su camino hacia los objetos raíz (GC roots). Esto mostrará quién mantiene la referencia, evitando la recolección de basura.
- Buscar referencias estáticas: Los campos estáticos a menudo son fuente de fugas si almacenan referencias de larga duración a contextos o vistas.
- Usar LeakCanary: La biblioteca automatiza la detección, volcado y análisis de fugas en tiempo de ejecución, proporcionando una descripción detallada del camino de la fuga.
-
Interpretación de resultados:
- Un camino largo hacia GC root que contiene referencias a objetos que deberían ser destruidos indica un problema.
- Las referencias desde campos estáticos, AsyncTask, Handlers con retrasos, listeners/callbacks no correctamente desregistrados, o singleton en actividades o vistas, a menudo son causa de fugas.
Ejemplo de análisis del camino hacia GC root en Android Studio Memory Profiler:
// Ejemplo de camino hacia GC root que indica una fuga
// android.app.Activity instancia con mDestroyed=true
// referencia a android.widget.LinearLayout
// referencia a android.view.View $ListenerInfo
// referencia a com.example.MyActivity$1 (clase anónima que implementa View.OnClickListener)
// referencia a com.example.MyActivity (referencia que provoca la fuga)
En este ejemplo, una clase anónima (el listener del botón) mantiene una referencia implícita a MyActivity, aunque la actividad ya debería estar destruida (mDestroyed=true). Este listener parece estar registrado o retenido por otro objeto de larga duración (por ejemplo, un campo estático o un singleton).