La optimización de la memoria es fundamental para ofrecer experiencias de juego estables y de alto rendimiento en Android. En esta guía, se proporciona una descripción general de por qué es importante la eficiencia de la memoria, cómo el sistema operativo Android administra y aplica los límites de memoria de los procesos, y los nuevos umbrales expuestos en Google Play Console para ayudarte a supervisar y mejorar la calidad técnica de tu juego.
La importancia de la optimización de la memoria
Optimizar la memoria de tu juego es fundamental para mantener la retención de jugadores, expandir la compatibilidad con dispositivos y cumplir con los estándares de calidad de la plataforma:
- Prevención del inicio en frío (experiencia del usuario y retención): Cuando un jugador se aleja temporalmente de tu juego (por ejemplo, para responder una notificación o consultar un mensaje), el sistema operativo coloca el proceso del juego en segundo plano. Si el uso de memoria en segundo plano del juego es demasiado alto, el optimizador de poca memoria (LMK) del sistema prioriza la finalización del proceso del juego para recuperar la RAM para las tareas en primer plano. La próxima vez que el usuario reanude el juego, en lugar de una reanudación instantánea y sin problemas, el juego deberá someterse a un inicio en frío prolongado, lo que implica volver a cargar por completo los recursos gráficos pesados, el audio y los objetos binarios del motor de juego desde el almacenamiento. Mantener bajo el uso de memoria en segundo plano evita estas finalizaciones silenciosas en segundo plano, preserva el estado del usuario y garantiza que los jugadores puedan reanudar su sesión de inmediato. Para obtener más detalles sobre el comportamiento del LMK del sistema, consulta la guía de Android Vitals: optimizadores de poca memoria.
- Estabilidad del ecosistema y del dispositivo: El uso ineficiente de la memoria y las fugas de memoria degradan el estado general del sistema. Cuando la memoria del sistema es escasa, el sistema enfrenta una presión severa, lo que provoca caídas en la velocidad de fotogramas, interrupciones en la IU y fallas de audio. Si la presión de la memoria es demasiado severa, el optimizador de poca memoria (LMK) del sistema finaliza de forma agresiva los procesos en segundo plano, lo que obliga a otras aplicaciones a experimentar inicios en frío lentos y a perder el estado del usuario cuando los jugadores cambian de tarea.
- Finalizaciones a nivel de la plataforma: A partir de Android 17 (nivel de API 37), el sistema es más proactivo en la finalización de procesos que usan demasiada memoria. Si el uso de tu juego es demasiado alto, el SO puede finalizar su proceso de forma abrupta sin generar un seguimiento de pila estándar.
- Compatibilidad con dispositivos: Si bien los dispositivos insignia tienen de 12 a 16 GB de RAM, una gran parte del público global de juegos usa dispositivos con 4 o 6 GB de RAM. La administración adecuada de la memoria garantiza que tu juego siga siendo accesible y con capacidad de respuesta en todos los niveles de hardware sin requerir paquetes de recursos complejos y separados.
Información sobre la memoria en Android
Para diseñar estrategias eficaces de asignación de memoria, los desarrolladores deben comprender cómo la plataforma de Android administra la memoria física y cómo mide el uso activo de tu juego.
Conceptos básicos de la memoria de Android
Para conocer los conceptos básicos sobre la administración de memoria a nivel de la plataforma, consulta la documentación oficial Descripción general de la administración de memoria. Este recurso abarca cuatro áreas de arquitectura:
- Descripción general de la memoria: Android usa la paginación y el mapeo de memoria (mmap) para administrar la RAM. No admite un archivo de intercambio tradicional en el disco; en cambio, se basa en la compresión de páginas (con zRAM) y la recuperación de páginas para liberar memoria física.
- Asignación de memoria entre procesos: Android comparte la RAM en todo el sistema. Asigna segmentos específicos para la ejecución de la máquina virtual Dalvik o ART, al tiempo que permite que los entornos de desarrollo nativo (como los motores de juegos de C++) soliciten memoria del segmento nativo del sistema.
- Administración de memoria de la app: Android, que opera bajo un modelo de varios procesos, espera que las aplicaciones supervisen su estado del ciclo de vida de forma dinámica y liberen voluntariamente los recursos innecesarios (como los gráficos y mapas de bits sin caché) para admitir el estado del sistema.
- Descripción general de los procesos y subprocesos: El sistema clasifica los procesos en una jerarquía según su visibilidad e importancia actuales percibidas por el usuario, lo que determina qué procesos se mantienen activos y cuáles se finalizan primero en condiciones de poca memoria.
La métrica de uso total de memoria
El limitador de memoria de Android 17 a nivel de la plataforma evalúa el consumo de procesos con el uso total de memoria en lugar del tamaño residente total (RSS) o el tamaño de la memoria virtual.
Uso total de memoria = RSS anónimo (RssAnon) + intercambio sin comprimir (VmSwap)
Para evitar que los juegos excedan los límites aplicados por la plataforma, los desarrolladores deben comprender exactamente lo que representan estas métricas a nivel del sistema. Para obtener más información sobre estas métricas, las asignaciones de RAM física y cómo se controlan las páginas respaldadas por archivos , consulta Información sobre las métricas de RSS y de intercambio en la guía Supervisa el uso de memoria.
Restricciones de memoria
Para mantener la estabilidad del sistema y garantizar que las aplicaciones no consuman recursos excesivos, la plataforma de Android aplica límites de memoria en los procesos en ejecución.
Limitador de memoria en Android 17 y versiones posteriores
Android 17 y versiones posteriores aplican límites estrictos de memoria por app con Linux cgroup v2 para evitar que las apps individuales causen inestabilidad en todo el sistema. Para obtener más detalles sobre la implementación técnica, consulta la Guía del limitador de memoria de AOSP y la entrada de blog Priorización de la eficiencia de la memoria: pasos esenciales para Android 17.
- Mecanismo: El limitador de memoria supervisa todos los procesos de la aplicación y
asigna límites de forma dinámica según el estado del ciclo de vida del proceso:
- Procesos visibles (primer plano): Se espera que los procesos de la app que muestran una IU ejecuten un conjunto de trabajo de recursos más grande y tengan un límite más generoso.
- Procesos no visibles (segundo plano o servicios): Los procesos de la app que realizan trabajo activo sin mostrar una IU están restringidos a un presupuesto más ajustado y restrictivo.
- Atributos del kernel: El servicio se basa en dos atributos principales:
memory.high: Es un límite flexible. Cuando se excede, el kernel limita el proceso y trata de recuperar la memoria de forma agresiva. Esta recuperación puede hacer que el juego experimente una degradación del rendimiento.memory.swap.max: Aplica un límite máximo estricto en el espacio de intercambio o zRAM que puede usar el proceso.
- Comportamiento de finalización: Si un proceso continúa asignando memoria anónima
más allá de
memory.highy agota su capacidad de intercambio, las asignaciones fallan, y el SO finaliza el proceso de forma silenciosa. Esta finalización se registra conApplicationExitInfoen el motivo de salida del limitador de memoria (disponible a partir de Android 17, 26Q4).
Supervisa el uso de memoria
Para optimizar de manera eficaz la memoria de tu juego, primero debes comprender cómo la plataforma Android mide su uso. Android 17 actualiza la métrica de aplicación de la memoria para hacer un seguimiento de la suma del RSS anónimo (RssAnon) y el intercambio sin comprimir (VmSwap), sin incluir la memoria respaldada por archivos ni la memoria privada de la GPU. En esta guía, se detalla cómo aprovechar las herramientas a nivel del sistema, como Perfetto y meminfo, implementar APIs de diagnóstico, como ProfilingManager y onTrimMemory, y extraer asignaciones de memoria precisas en Unity y Unreal Engine. Comprende cómo generar perfiles de tu juego con precisión y evitar las interrupciones de rendimiento asociadas con el sondeo tradicional de memoria en el tiempo de ejecución.
Para obtener más información, consulta Supervisa el uso de memoria.
Estrategias de reducción de memoria
Si bien los motores de juegos simplifican el desarrollo multiplataforma, su control de memoria predeterminado puede activar límites de memoria a nivel del SO. En esta página, se detallan los pasos prácticos de optimización diseñados específicamente para Unity y Unreal Engine. Comprende por qué depender de onTrimMemory basado en Java puede causar interbloqueos en Unity y cómo usar devoluciones de llamada nativas del ciclo de vida en su lugar. También descubrirás optimizaciones clave a nivel de los recursos, como el uso de la compresión de texturas ASTC 8x8 y la configuración de descargas de recursos, para que tu juego se ejecute sin problemas en todos los niveles de hardware.