Android 17 y versiones posteriores admiten el daemon de administración de memoria (mmd), un daemon del sistema que controla la configuración del daemon, los parámetros ajustables y las tareas de mantenimiento en curso de intercambio o ZRAM.
Fondo
Antes de la introducción de mmd, las configuraciones de ZRAM de Android estaban fragmentadas y ofrecían una personalización limitada. mmd aborda este problema centralizando la administración de ZRAM, lo que permite una lógica de configuración más sofisticada y simplifica la incorporación de nuevas funciones y mejoras arquitectónicas.
mmd también establece una separación clara de las responsabilidades entre el proceso system_server basado en Java y el intercambio a nivel del kernel o la administración de memoria.
Arquitectura y administración de ZRAM
Cuando se completa el inicio (es decir, cuando sys.boot_completed=1), mmd_setup intenta configurar ZRAM con los parámetros especificados. Una vez que se completa la configuración de ZRAM, el sistema habilita el servicio mmd, que controla las tareas de mantenimiento en curso.
Con el proyecto mmd, las operaciones de mantenimiento se inician desde system_server enviando solicitudes de Binder a mmd con la interfaz IMmd.
mmd controla las tareas de mantenimiento de la escritura diferida de ZRAM, la recompresión y la escritura diferida por proceso según su propio motor de políticas interno. Tanto la programación de ActivityManagerService como las políticas de mantenimiento de ZRAM se pueden configurar con propiedades del sistema.
Integración del servidor del sistema (system_server)
El proceso system_server basado en Java determina cuándo se invoca mmd. El proceso separa las limpiezas de mantenimiento globales de las optimizaciones de memoria específicas para cada app.
Mantenimiento normal de posprocesamiento
El mantenimiento global de ZRAM se controla con ActivityManagerService a través de com.android.server.memory.ZramMaintenance.

Figura 1: Es el flujo de programación del mantenimiento de ZRAM.
- Motor de programación:
ZramMaintenanceregistra un trabajo periódico en segundo plano conJobSchedulerde Android. - Restricciones del trabajo: Para evitar la interrupción de la IU en primer plano o la contención de la CPU, el trabajo se configura de forma explícita con
setRequiresDeviceIdle(true)ysetRequiresBatteryNotLow(true). - Activación del vinculador: Cuando el programador activa
onStartJob(),system_serverinvocammd.doZramMaintenanceAsync(). Esta es una llamada de Binder asíncrona unidireccional;system_serverno se bloquea a la espera de que finalicen los análisis de mantenimiento.mmdpone en cola esta operación en un subproceso de trabajo en segundo plano para realizar la recompresión y la escritura de forma secuencial.
Escritura diferida por proceso
ActivityManagerService administra el desalojo de memoria por proceso segmentado con com.android.server.am.CachedAppOptimizer.

Figura 2: Flujo de escritura diferida por proceso de mmd
Cuando un proceso pasa a un estado almacenado en caché en segundo plano, ActivityManager realiza una compactación de memoria. Si la eliminación del proceso por falta de memoria sería visible para el usuario, es decir, si el proceso aloja una Activity y si la escritura diferida de ZRAM por proceso llevaría el espacio de memoria del proceso a casi cero, el sistema sigue estos pasos:
- Después de la compactación,
CachedAppOptimizerpublica un mensaje retrasado (ZRAM_WRITEBACK_MSG) en su controlador de compactación interno (retrasado pormZramWritebackWaitSeconds). - Cuando vence la demora, ActivityManager abre un descriptor de archivo de proceso seguro
pidfd. - El servidor del sistema llama a
mmd.asyncWritebackProcessZramMemory(pfd, callback). mmdejecuta el ioctl de escritura diferida por proceso y envía un informe conIMmdProcessWritebackCallback. Si se realiza correctamente, ActivityManager marca el registro del proceso (setIsZramWrittenBack(app, true)) para aumentar eloom_score_adjdel proceso y registra métricas enFrameworkStatsLog.ZRAM_WRITEBACK_EVENT.
Carga previa por proceso
Cuando un usuario reinicia una app almacenada en caché anteriormente (descongelada debido a UNFREEZE_REASON_ACTIVITY), ActivityManager minimiza la latencia de inicio de la app causada por errores de página importantes del almacenamiento de respaldo:
CachedAppOptimizerintercepta el evento de descongelación y, luego, invocaprefetchZram(app).- El servidor del sistema envía el
pidfdde la app a través de Binder conmmd.asyncPrefetchProcessZramMemory(pfd).mmdemite el ioctlZRAM_ANDROID_IOC_PROCESS_PREFETCH, lo que indica al kernel que realice una carga previa asíncrona de las páginas intercambiadas en la RAM mientras se inicializa el subproceso de IU principal de la app.
Descripción general de las tareas de mantenimiento y procesamiento posterior
En esta sección, se describen las operaciones de mantenimiento en segundo plano y las tareas de procesamiento posterior que ejecuta mmd para optimizar el espacio de intercambio y la memoria del sistema.
Mantenimiento en mmd
En mmd, el término mantenimiento hace referencia a las verificaciones de mantenimiento programadas en segundo plano que optimizan el espacio de intercambio y la utilización de la memoria física sin afectar el rendimiento en primer plano del usuario activo. En lugar de realizar barridos continuos y síncronos (que provocarían activaciones graves de la CPU y bloqueos de la IU), el mantenimiento se realiza de forma asíncrona:
system_serveractivadoZramMaintenanceAsync()periódicamente en Binder.mmdcoloca la solicitud en una cola de trabajo en segundo planoLowPrioWorkItem::ZramMaintenance.Hay un solo subproceso de trabajo en
mmdque administra una cola de prioridad alta y una cola de prioridad baja. Los elementos de trabajo de prioridad alta (como la recuperación previa por proceso) se procesan primero y pueden interrumpir los elementos de trabajo de prioridad baja. El mantenimiento y la escritura diferida por proceso operan como elementos de trabajo de baja prioridad. Cuando se extrae, el subproceso de trabajo ejecuta dos operaciones de mantenimiento principales de forma secuencial:Recompresión de ZRAM: Analiza las páginas de intercambio existentes y recompresa las páginas inactivas con un algoritmo de compresión secundario de mayor proporción, por ejemplo,
zstd.Escritura diferida de zRAM: Analiza las páginas inactivas y las expulsa por completo de la RAM al almacenamiento flash de respaldo, un dispositivo de bucle desde un archivo en
/data.
Tareas de posprocesamiento en ZRAM
En el módulo ZRAM del kernel de Linux y la arquitectura mmd, las tareas de procesamiento posterior son las transformaciones asíncronas que se aplican a las páginas de memoria después de que el kernel ya las haya intercambiado con las rutas de recuperación estándar del kernel (kswapd o compactación).
Cuando se reemplaza una página inicialmente, el sistema prioriza la velocidad: usa un algoritmo de compresión principal rápido (como lz4) y almacena la página comprimida en la RAM. Sin embargo, con el tiempo, muchas páginas intercambiadas se vuelven inactivas, por ejemplo, las apps almacenadas en caché en segundo plano que no se reanudan durante horas. Dejar páginas frías en la ZRAM rápida y ligeramente comprimida es ineficiente.
Canalización de posprocesamiento
mmd implementa un ciclo de vida de procesamiento posterior de varias etapas para optimizar estas páginas:

Figura 3: Ciclo de vida de la página mmd.
Etapa 1: Intercambio inicial (compresión rápida): Primero, se recupera la memoria a través de kswapd o la compactación de la app. Por lo general, esta primera recuperación se realiza con un algoritmo de compresión rápido, como
lz4, y el contenido se almacena en la RAM.Etapa 2: Marcado de inactividad (antigüedad y seguimiento): El seguimiento de inactividad de
mmdaccede al seguimiento de la memoria del kernel (CONFIG_ZRAM_TRACK_ENTRY_ACTIME) o usa su marcador de inactividad de software para hacer un seguimiento del tiempo que las páginas permanecieron sin tocar.Etapa 3: Postprocesamiento 1: recompresión (recuperación en memoria): Las páginas que alcanzan la antigüedad de inactividad de recompresión (
min_idle_secondsamax_idle_seconds) se someten a recompresión.mmdescribe en/sys/block/zram0/recompresspara indicarle al kernel que descomprima la páginalz4y la vuelva a comprimir conzstd. Esto recupera la RAM física sin generar desgaste por escritura en la memoria flash.Etapa 4: Postprocesamiento 2: Escritura diferida (desalojo al almacenamiento flash): Si la presión de memoria continúa y las páginas alcanzan la antigüedad de inactividad de escritura diferida (por lo general, 20 horas o más),
mmdactiva la escritura diferida.mmdescribe en/sys/block/zram0/idley/sys/block/zram0/writebackpara expulsar la página comprimida por completo de la RAM al almacenamiento flash de respaldo.
Configuración de ZRAM
mmd carga y procesa las siguientes propiedades de configuración de ZRAM:
| Propiedad | Usar | Predeterminado |
|---|---|---|
mmd.zram.enabled |
Indica si está habilitada la configuración de mmd ZRAM. |
false |
mmd.zram.num_devices |
Es la cantidad de dispositivos ZRAM que se configurarán. Para un número N, los dispositivos zram0 a zram<N-1> deben estar presentes antes de que el sistema establezca sys.boot_completed=1.
Las propiedades de la lista de dispositivos por ZRAM se pueden configurar por dispositivo.
|
1 |
mmd.zram.device_priority |
Son los valores de prioridad que se deben pasar cuando se llama a swapon. |
Sin establecer |
mmd.zram.comp_algorithm |
Algoritmo de compresión de ZRAM. Si no se especifica, se usa el algoritmo de compresión predeterminado del kernel. | Sin establecer |
mmd.zram.size |
Tamaño del dispositivo zRAM en bytes o un porcentaje del tamaño de la RAM del dispositivo, por ejemplo, 75%.
|
50% |
mmd.zram.writeback.enabled |
Indica si se debe habilitar la escritura diferida de ZRAM. | false |
mmd.zram.writeback.device_size |
Tamaño del dispositivo de escritura diferida en bytes o porcentaje de la partición de datos. El tamaño real del dispositivo se puede ajustar según el espacio disponible en la partición de datos. | 1073741824 (1 GiB) |
mmd.zram.writeback.min_free_space_mib |
Es el espacio libre mínimo en MiB que debe estar disponible después de configurar el dispositivo de escritura diferida. | 1536 (1.5 GiB) |
mmd.zram.writeback.use_nr_tags_prop |
Cuando es true, usa el valor de mmd.zram.writeback.nr_tags para configurar la profundidad de la cola de la escritura diferida de ZRAM que respalda el dispositivo de bucle. Esta es una solución alternativa para situaciones en las que no se puede configurar la política de SELinux del proveedor para permitir que mmd lea directamente nr_tags del dispositivo de bloqueo que respalda /data.
|
false |
mmd.zram.writeback.nr_tags |
Consulta mmd.zram.writeback.use_nr_tags_prop. |
Sin establecer |
mmd.zram.recompression.enabled |
Indica si se debe habilitar la función de recompresión de ZRAM. | false |
mmd.zram.recompression.algorithm |
Es el algoritmo secundario de recompresión de ZRAM. | zstd |
Propiedades del dispositivo por ZRAM
Cuando mmd.zram.num_devices es mayor que uno, se pueden configurar propiedades específicas de forma opcional para cada dispositivo ZRAM estableciendo la propiedad en un valor separado por comas que contenga exactamente mmd.zram.num_devices elementos.
Estas propiedades incluyen la siguiente información:
mmd.zram.sizemmd.zram.comp_algorithmmmd.zram.device_prioritymmd.zram.recompression.enabledmmd.zram.recompression.huge_idle.enabledmmd.zram.recompression.idle.enabledmmd.zram.recompression.huge.enabledmmd.zram.recompression.threshold_bytesmmd.zram.recompression.algorithmmmd.zram.writeback.device_sizemmd.zram.writeback.huge_idle.enabledmmd.zram.writeback.idle.enabledmmd.zram.writeback.huge.enabled
Baja de la configuración existente de ZRAM
Si bien swapon_all sigue disponible en Android para configurar el espacio de intercambio basado en disco y ZRAM, mmd es el enfoque preferido para la administración de ZRAM, ya que facilita la configuración y ofrece funciones avanzadas, como la recompresión de ZRAM.
Cuando mmd.zram.enabled habilita la configuración de mmd ZRAM, ocurre lo siguiente:
- La configuración de ZRAM en la implementación de
swapon_allse convierte en una operación sin efecto. - Se ignoran las configuraciones de ZRAM existentes, como
config_zramWritebacken el archivo de superposiciónconfig.xmly las propiedades del sistema de escritura diferidaro.zram.*.
Parámetros de ajuste de mantenimiento de ZRAM
El mantenimiento de ZRAM debería funcionar de inmediato, y puedes ajustarlo aún más con las propiedades del sistema que se indican en esta sección.
Programación del mantenimiento de ZRAM
Estas propiedades controlan cómo y cuándo system_server programa las tareas de mantenimiento de ZRAM.
| Propiedad | Usar | Predeterminado |
|---|---|---|
mm.zram.maintenance.first_delay_seconds |
Es la demora antes de que se inicie el primer mantenimiento de ZRAM. | 3600 (1 hora) |
mm.zram.maintenance.periodic_delay_seconds |
Es la demora entre las programaciones de mantenimiento de ZRAM posteriores. | 3600 (1 hora) |
mm.zram.maintenance.require_device_idle |
Indica si solo se debe iniciar el mantenimiento de ZRAM cuando el dispositivo está inactivo. | true |
mm.zram.maintenance.require_battery_not_low |
Indica si se debe requerir que la batería no esté baja antes de iniciar el mantenimiento de ZRAM. | true |
Política de escritura diferida de ZRAM
Los siguientes parámetros controlan cuándo y qué tipo de memoria se escribe en el dispositivo de respaldo:
| Propiedad | Usar | Predeterminado |
|---|---|---|
mmd.zram.writeback.backoff_seconds |
Es el tiempo de espera desde la última operación de escritura diferida. | 600 (10 minutos) |
mmd.zram.writeback.min_idle_seconds |
Se combina con mmd.zram.writeback.max_idle_seconds para calcular la antigüedad de inactividad de una página y determinar si es apta para la escritura diferida según la fracción de utilización de la memoria. La antigüedad de inactividad calculada se interpola de forma exponencial entre los dos parámetros para minimizar el trabajo cuando no hay presión de memoria.
|
72000 (20 horas) |
mmd.zram.writeback.max_idle_seconds |
Cantidad máxima de segundos que se usan para calcular la antigüedad de la página inactiva de forma dinámica según el uso de la memoria. | 90000 (25 horas) |
mmd.zram.writeback.huge.enabled |
Indica si se debe habilitar la escritura diferida de la página HUGE. |
false |
mmd.zram.writeback.idle.enabled |
Indica si se debe habilitar la escritura diferida de la página IDLE. |
true |
mmd.zram.writeback.huge_idle.enabled |
Indica si se debe habilitar la escritura diferida de la página HUGE_IDLE. |
true |
mmd.zram.writeback.min_bytes |
Es la cantidad mínima de bytes que se deben escribir en una ronda de escritura en segundo plano inactiva. | 5242880 (5 MiB) |
mmd.zram.writeback.max_bytes |
Cantidad máxima de bytes que se pueden escribir en una ronda de escritura en segundo plano inactiva. | 314572800 (300 MiB) |
mmd.zram.writeback.max_bytes_per_day |
Cantidad máxima de bytes que se pueden escribir en un período de 24 horas. | 25769803776 (24 GiB) |
mmd.zram.writeback.limit.enabled |
Indica si se debe habilitar la contabilización del límite de presupuesto de reversión diaria. | true |
Política de recompresión de ZRAM
Los siguientes parámetros controlan cuándo y qué tipo de memoria se vuelve a comprimir:
| Propiedad | Usar | Predeterminado |
|---|---|---|
mmd.zram.recompression.backoff_seconds |
Es el tiempo de espera desde la última recompresión. | 1800 (30 minutos) |
mmd.zram.recompression.min_idle_seconds |
Se combina con mmd.zram.recompression.max_idle_seconds para calcular la antigüedad de inactividad de una página y determinar si es apta para la recompresión según la fracción de utilización de la memoria. La antigüedad de inactividad calculada se interpola de forma exponencial entre los dos parámetros para minimizar el trabajo cuando no hay presión de memoria.
|
7200 (2 horas) |
mmd.zram.recompression.max_idle_seconds |
Es la cantidad máxima de segundos que se usa para calcular de forma dinámica la antigüedad de la página inactiva. | 14400 (4 horas) |
mmd.zram.recompression.threshold_bytes |
Es el tamaño mínimo en bytes de las páginas de ZRAM que se consideran para la recompresión. | 1024 (1 KiB) |
mmd.zram.recompression.huge.enabled |
Indica si se debe habilitar la recompresión de la página HUGE. |
true |
mmd.zram.recompression.idle.enabled |
Indica si se debe habilitar la recompresión de la página IDLE. |
true |
mmd.zram.recompression.huge_idle.enabled |
Indica si se debe habilitar la recompresión de la página HUGE_IDLE. |
true |
Seguimiento de páginas inactivas de zRAM
mmd El mantenimiento de ZRAM marca las páginas de ZRAM como inactivas según el tiempo que haya transcurrido desde el último acceso. Esta función requiere que se habiliten las configuraciones del kernel CONFIG_ZRAM_TRACK_ENTRY_ACTIME o CONFIG_ZRAM_MEMORY_TRACKING. CONFIG_ZRAM_TRACK_ENTRY_ACTIME está habilitado de forma predeterminada en los kernels de GKI 6.18 y versiones posteriores. En kernels anteriores, tiene una sobrecarga de memoria y no está habilitado de forma predeterminada.
Si la configuración del kernel no está habilitada, el mantenimiento de mmd ZRAM recurre a una lógica de sustitución de software para hacer un seguimiento de las páginas de ZRAM inactivas:
Marcar todas las páginas de ZRAM como inactivas cuando se inicia
mmdSe omitirán los próximos mantenimientos de ZRAM hasta que haya pasado el período de espera requerido.
Escribir en zRAM o volver a comprimir las páginas inactivas Si quedan páginas inactivas debido a los límites de escritura diferida,
mmdcontinúa escribiendo páginas en el próximo mantenimiento sin marcar páginas nuevas como inactivas (se omite el paso 4).Si se vuelven a escribir todas las páginas inactivas, vuelve a marcar todas las páginas de ZRAM como inactivas y regresa al paso 2. Si la escritura diferida de ZRAM está inhabilitada,
mmdmarca todas las páginas de ZRAM como inactivas cuando se produce la recompresión de ZRAM después de la duración de inactividad de recompresión.
Orientación para la solución de problemas y la validación
Usa los siguientes pasos de validación y procedimientos de solución de problemas para verificar y diagnosticar las operaciones de mmd y ZRAM.
Valida la configuración de ZRAM
Para verificar que mmd configuró correctamente ZRAM durante el inicio, haz lo siguiente:
Verifica el algoritmo de compresión activo y el tamaño del disco:
cat /sys/block/zram0/comp_algorithm cat /sys/block/zram0/disksizeVerifica las propiedades del sistema
mmdy el estado del servicio en ejecución:getprop | grep mmd.zram dumpsys -l | grep mmd
Valida el mantenimiento y la escritura diferida de ZRAM
Verifica que las tareas de mantenimiento de escritura diferida y recompresión de ZRAM funcionen correctamente:
Verifica el estado del dispositivo de bloqueo de respaldo:
cat /sys/block/zram0/bd_statSupervisa
/sys/block/zram0/mm_statpara verificar la eficiencia de la recompresión. Los cambios en los tamaños de los datos comprimidos deberían aparecer después de los ciclos de mantenimiento.
Valida la escritura diferida por proceso
Se puede usar lo siguiente para validar que la escritura diferida por proceso funciona:
- Verifica
adb logcat -s mmdpara ver si hay registros de escritura exitosos o diagnósticos de fallas.
Problemas y diagnósticos habituales
A continuación, se muestran situaciones de error comunes que el usuario puede encontrar:
WritebackDailyLimitExceeded: Este error indica que se alcanzó la cuota demmd.zram.writeback.max_bytes_per_day. Cuando esto ocurre,mmdpausa la escritura diferida inactiva hasta que avanza el período continuo de 24 horas.Process prefetch or writeback failed: Este error se puede observar en logcat cuando falla un ioctl. Entre las causas comunes, se incluyen las siguientes:EBADFoESRCH: El proceso de destino finalizó antes de quemmdpudiera enviarpidfdal kernel.ENOSPC: La partición de almacenamiento de respaldo está llena o se agotó la cola del dispositivo de bucle.
- ZRAM no configurado: Si
mmdno logra configurar ZRAM durante el inicio, es posible que los scripts de inicio heredados deswapon_allo del proveedor hayan bloqueado/dev/block/zram0antes de que se pudiera ejecutarmmd.