Android 17 y versiones posteriores admiten el daemon de protección de memoria de procesos (PMGD), que protege el estado del sistema y la experiencia del usuario administrando de forma proactiva el uso de memoria por proceso. El daemon mejora la estabilidad general del dispositivo, ya que aplica límites de memoria de forma correcta en procesos de destino específicos y verifica que las fugas o los picos de memoria aislados no provoquen una degradación del rendimiento en todo el sistema.
Mientras que los killers convencionales de memoria baja global actúan solo cuando todo el sistema está bajo presión, PMGD adopta un enfoque granular. El daemon logra esto supervisando los valores de memoria del grupo de control v2 para sus procesos objetivo.
Cuando un proceso objetivo supera los límites de memoria configurados, pmgd controla los incumplimientos de límites registrando átomos de memoria de Statsd antes de finalizar el proceso.
Cómo funciona
El daemon usa inotify para escuchar eventos de presión de memoria (específicamente, actividad de memoria alta con memory.events). Cuando un proceso supervisado activa un evento de memoria, pmgd realiza las siguientes acciones:
- Verificación de memoria anónima: Evalúa la memoria anónima del proceso. Si supera el
anon_limit_in_mbconfigurado,pmgdinterrumpe el proceso de inmediato. - Período de espera de recuperación: Si la memoria anónima está por debajo del límite especificado,
pmgdespera un período de gracia de recuperación del sistema (reclaim_wait_time_secs). - Evaluación de la memoria después de la recuperación: Si el valor de
memory.currentdel proceso objetivo sigue siendo mayor o igual quememory.highdespués del período de gracia, o si la memoria anónima superaanon_limit_in_mb,pmgdfinaliza el proceso de inmediato.
Esto se hace de forma continua hasta que se finaliza el proceso o hasta que la recuperación del proceso reduce su uso de memoria por debajo de los límites de memoria especificados.
Funciones de estado del sistema
- Limitación de la tasa de reinicio: Para evitar bucles de inicio o fallas persistentes,
pmgdhace un seguimiento de las finalizaciones de procesos en/data/misc/pmgd/history.json. El daemon restringe los procesos a una sola eliminación iniciada porpmgdpor cada reinicio del dispositivo.
Configuración de SELinux
La capacidad de PMGD para supervisar procesos está restringida por la política de SELinux. Si configuras PMGD para supervisar un proceso cuyo dominio no está permitido por la política, como un proceso del sistema específico del proveedor, PMGD no podrá supervisarlo y es posible que veas denegaciones de SELinux en logcat.
Para permitir que PMGD supervise procesos en dominios adicionales, debes extender los permisos de PMGD actualizando la política de SELinux específica del dispositivo para PMGD.
El siguiente es un ejemplo de un archivo device/<vendor>/<device>/sepolicy/pmgd.te que agrega acceso a un dominio nuevo:
# Allow pmgd to access vendor_system_apps
r_dir_file(pmgd, vendor_system_apps)
Para obtener más información sobre cómo escribir políticas específicas del dispositivo, consulta Implementa SELinux.
Configuración definida por el proveedor
La configuración de PMGD se basa en el proveedor y se configura con un archivo JSON obligatorio /vendor/etc/pmgd/config.json. En esta lista, se indican los procesos que se deben hacer un seguimiento, su perfil de límite de memoria configurado (con perfiles de tareas de cgroup) y el límite de memoria anónima fijo en megabytes.
Campos de configuración del proveedor
La configuración JSON proporcionada es una lista de procesos y sus límites, definidos por los siguientes campos:
| Campo | Tipo | Obligatorio | Descripción | Predeterminado |
|---|---|---|---|---|
target_cmd |
String | Sí | Nombre del comando del proceso objetivo que se supervisará, por ejemplo, system_server. |
N/A |
uid |
Número entero | No | Es el ID de usuario (UID) del proceso. Si se omite, pmgd aplica la regla de forma global a cualquier proceso que coincida con target_cmd. |
N/A |
reclaim_wait_time_secs |
Número entero | No | Es el período de gracia en segundos que se espera para que el sistema recupere memoria antes de volver a evaluar el límite de memoria. | 5 |
mem_limit_profile |
String | Sí | Nombre del perfil de tarea de cgroup que establece `memory.high`. Se usa para establecer el límite de memoria del proceso. | N/A |
anon_limit_in_mb |
Número entero | Sí | Límite de memoria anónimo final en megabytes. Si la utilización de memoria anónima supera este valor, pmgd detiene el proceso de inmediato. |
N/A |
additional_task_profiles |
Lista de strings | No | Es una lista de los perfiles de tareas adicionales a los que se aplica pmgd en el proceso cuando comienza la supervisión. |
Lista vacía |
A continuación, se muestra un ejemplo de la configuración del perfil de tareas de cgroup en vendor/etc/task_profiles.json:
{
"Attributes": [
...
{
"Name": "MemHigh",
"Controller": "memory",
"File": "memory.high"
}
],
"Profiles": [
{
"Name": "SystemServerMemoryHighLimit",
"Actions": [
{
"Name": "SetAttribute",
"Params":
{
"Name": "MemHigh",
"Value": "1080M"
}
}
]
}
]
}
A continuación, se muestra un ejemplo de la configuración de PMGD en vendor/etc/pmgd/config.json:
{
"targets": [
{
"target_cmd": "system_server",
"uid": 1000,
"reclaim_wait_time_secs": 5,
"mem_limit_profile": "SystemServerMemoryHighLimit",
"anon_limit_in_mb": 300
}
]
}