O Android 17 e versões mais recentes oferecem suporte ao daemon guardião de memória de processo (PMGD, na sigla em inglês), que protege a integridade do sistema e a experiência do usuário gerenciando proativamente o uso da memória por processo. O daemon melhora a estabilidade geral do dispositivo aplicando limites de memória de maneira adequada em processos de destino específicos, verificando se vazamentos ou picos de memória isolados não causam degradação no desempenho de todo o sistema.
Enquanto os eliminadores globais convencionais de pouca memória agem apenas quando todo o sistema está sob pressão, o PMGD adota uma abordagem granular. O daemon faz isso monitorando os valores de memória do grupo de controle v2 dos processos de destino.
Quando um processo segmentado excede os limites de memória configurados, o pmgd
processa as violações de limite registrando átomos de memória do Statsd antes de encerrar
o processo.
Como funciona
O daemon usa inotify para detectar eventos de pressão de memória (especificamente
atividade de uso intenso de memória usando memory.events). Quando um processo monitorado aciona um
evento de memória, pmgd realiza as seguintes ações:
- Verificação anônima de memória:avalia a memória anônima do processo. Se exceder o
anon_limit_in_mbconfigurado, opmgdvai encerrar o processo imediatamente. - Período de espera de recuperação:se a memória anônima estiver abaixo do limite especificado, o
pmgdaguardará um período de carência de recuperação do sistema (reclaim_wait_time_secs). - Avaliação da memória após a recuperação:se o
memory.currentdo processo de destino permanecer maior ou igual amemory.highapós o período de carência, ou se a memória anônima excederanon_limit_in_mb,pmgdvai encerrar o processo imediatamente.
Isso é feito continuamente até que o processo seja encerrado ou a recuperação no processo reduza o uso da memória abaixo dos limites de memória especificados.
Recursos de saúde do sistema
- Limitação de taxa de reinicialização:para evitar loops de inicialização ou falhas persistentes, o
pmgdrastreia a interrupção de processos em/data/misc/pmgd/history.json. O daemon restringe os processos a uma única interrupção iniciada porpmgdpor reinicialização do dispositivo.
Configuração do SELinux
A capacidade do PMGD de monitorar processos é restrita pela política do SELinux. Se você configurar o PMGD para monitorar um processo cujo domínio não é permitido pela política, como um processo do sistema específico do fornecedor, o PMGD não poderá monitorá-lo, e você poderá ver negações do SELinux no logcat.
Para permitir que o PMGD monitore processos em domínios adicionais, você deve estender as permissões do PMGD atualizando a política do SELinux específica do dispositivo para o PMGD.
A seguir, um exemplo de arquivo device/<vendor>/<device>/sepolicy/pmgd.te
que adiciona acesso a um novo domínio:
# Allow pmgd to access vendor_system_apps
r_dir_file(pmgd, vendor_system_apps)
Para mais informações sobre como escrever uma política específica do dispositivo, consulte Implementar o SELinux.
Configuração definida pelo fornecedor
A configuração do PMGD é orientada pelo fornecedor e configurada por um arquivo JSON obrigatório
/vendor/etc/pmgd/config.json. Isso lista os processos a serem rastreados, o perfil de limite de memória configurado (usando perfis de tarefas do cgroup) e o limite de memória anônima fixa em megabytes.
Campos de configuração do fornecedor
A configuração JSON fornecida é uma lista de processos e limites, definidos pelos seguintes campos:
| Campo | Tipo | Obrigatório | Descrição | Padrão |
|---|---|---|---|---|
target_cmd |
String | Sim | O nome do comando do processo de destino a ser monitorado, por exemplo, system_server. |
N/A |
uid |
Número inteiro | Não | O ID de usuário (UID) do processo. Se omitido, pmgd aplica a regra globalmente a qualquer processo que corresponda a target_cmd. |
N/A |
reclaim_wait_time_secs |
Número inteiro | Não | O período de carência em segundos para aguardar que o sistema recupere a memória antes de avaliar o limite novamente. | 5 |
mem_limit_profile |
String | Sim | O nome do perfil de tarefa do cgroup que define "memory.high". Isso é usado para definir o limite de memória do processo. | N/A |
anon_limit_in_mb |
Número inteiro | Sim | O limite máximo de memória anônima em megabytes. Se a utilização de memória anônima ultrapassar esse valor, o pmgd vai encerrar o processo imediatamente. |
N/A |
additional_task_profiles |
Lista de strings | Não | Uma lista de outros perfis de tarefa a que pmgd se aplica
ao processo quando o monitoramento é iniciado. |
Lista vazia |
Confira a seguir um exemplo de configuração do perfil de tarefa do cgroup
em vendor/etc/task_profiles.json:
{
"Attributes": [
...
{
"Name": "MemHigh",
"Controller": "memory",
"File": "memory.high"
}
],
"Profiles": [
{
"Name": "SystemServerMemoryHighLimit",
"Actions": [
{
"Name": "SetAttribute",
"Params":
{
"Name": "MemHigh",
"Value": "1080M"
}
}
]
}
]
}
Confira a seguir um exemplo de configuração do PMGD em
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
}
]
}