Comprensión y solución de problemas de la memoria de Android

La memoria es un recurso fundamental y finito en los dispositivos con tecnología Android. Como desarrollador de la plataforma de Android o OEM, comprender cómo funciona la memoria en todos los niveles, desde el entorno de ejecución de Java hasta el kernel de Linux, es esencial para crear un sistema estable y de alto rendimiento.

En esta guía, se proporciona una descripción general completa de la arquitectura de memoria de Android, las herramientas disponibles para el análisis y ejercicios prácticos para ayudarte a identificar y resolver problemas relacionados con la memoria.

Objetivos

Después de completar esta guía, podrás hacer lo siguiente:

  • Explicar los conceptos fundamentales de la memoria de Android, incluido el modelo de proceso de Zygote y los archivos asignados a la memoria
  • Diferenciar entre el tamaño del conjunto residente (RSS), el tamaño del conjunto proporcional (PSS) y el tamaño del conjunto único (USS)
  • Usar herramientas de línea de comandos estándar, como dumpsys meminfo y showmap, para evaluar rápidamente el uso de memoria.
  • Capturar y analizar volcados de montón de Java con AHAT para encontrar pérdidas y asignaciones excesivas
  • Usar Perfetto y heapprofd para generar perfiles de la memoria nativa y de Java en todo el sistema
  • Comprender los indicadores de presión de memoria en todo el sistema, como la información de bloqueo de presión (PSI), y supervisar la actividad de Low Memory Killer (LMK)
  • Observar la actividad de recuperación a nivel del kernel, incluido el intercambio de ZRAM y el desalojo de la caché de páginas

Estructura de la guía

Esta guía está organizada en las siguientes secciones, diseñadas para leerse de forma secuencial:

  1. Conceptos fundamentales: Los principios técnicos básicos de la memoria de Android.
  2. Herramientas de evaluación rápida: Uso de meminfo, showmap, y procstats para la clasificación rápida
  3. Análisis de la memoria de Java: Análisis detallados del montón de Java con AHAT.
  4. Mapas de bits y memoria: Comprender cómo las imágenes afectan la RAM y usar herramientas para generar perfiles
  5. Análisis de la memoria nativa: Generación de perfiles de la memoria C/C++ con Perfetto y heapprofd.
  6. WebView y espacio en memoria: Comprender la arquitectura de varios procesos y el espacio en memoria de WebViews.
  7. El código de la app es memoria: Comprender cómo la carga de clases y el aumento de dex afectan la RAM.
  8. Subprocesos y memoria: Análisis del costo de las pilas de subprocesos nativos
  9. **Localidad de la memoria y rendimiento**: Comprender cómo los patrones de acceso a los datos afectan el rendimiento de la CPU
  10. Vinculaciones de servicios y estados de procesos: Comprender cómo las dependencias entre procesos afectan las puntuaciones de OOM
  11. Solución de problemas en todo el sistema: Supervisión de PSI, LMK, intercambio de ZRAM y desalojo de la caché de páginas
  12. Recuperación de memoria: desalojo e intercambio: Comprender memcg, la carga y la recuperación proactiva con memory.reclaim.
  13. Interacción de kswapd y lmkd: Comprender cómo kswapd y lmkd funcionan juntos bajo presión

Requisitos previos y entorno

En esta guía, se presentan flujos de trabajo de referencia, datos de comparativa y casos prácticos que demuestran cómo diagnosticar y resolver problemas de memoria de Android.

  • Herramientas de análisis: Las técnicas de esta guía usan principalmente herramientas de rendimiento estándar de Android, incluidas Perfetto, dumpsys meminfo, showmap, y AHAT.
  • Privilegios de administrador: Algunos flujos de trabajo de diagnóstico a nivel del sistema (como la inspección de la presión de la memoria del kernel o los contadores PMU de hardware) requieren privilegios de administrador elevados (adb root) en una compilación de emulador o dispositivo userdebug.

Comienza aquí: Conceptos fundamentales