O processo Android low memory killer daemon ( lmkd
) monitora o estado da memória de um sistema Android em execução e reage à alta pressão de memória eliminando os processos menos essenciais para manter o desempenho do sistema em níveis aceitáveis.
Sobre pressão de memória
Um sistema Android executando vários processos em paralelo pode encontrar situações em que a memória do sistema se esgota e os processos que exigem mais memória apresentam atrasos perceptíveis. A pressão de memória , um estado em que o sistema está com pouca memória, exige que o Android libere memória (para aliviar a pressão), limitando ou eliminando processos sem importância, solicitando processos para liberar recursos não críticos em cache e assim por diante.
Historicamente, o Android monitorava a pressão da memória do sistema usando um driver LMK (Low Memory Killer) no kernel, um mecanismo rígido que depende de valores codificados. A partir do kernel 4.12, o driver LMK é removido do kernel upstream e o espaço do usuário lmkd
executa tarefas de monitoramento de memória e eliminação de processos.
Informações de parada de pressão
O Android 10 e versões posteriores oferecem suporte a um novo modo lmkd
que usa monitores PSI (informações de travamento de pressão do kernel) para detecção de pressão de memória. O patchset PSI no kernel upstream (portado para os kernels 4.9 e 4.14) mede a quantidade de tempo que as tarefas são atrasadas como resultado de falta de memória. Como esses atrasos afetam diretamente a experiência do usuário, eles representam uma métrica conveniente para determinar a gravidade da pressão de memória. O kernel upstream também inclui monitores PSI que permitem que processos de espaço de usuário privilegiados (como lmkd
) especifiquem limites para esses atrasos e assinem eventos do kernel quando um limite for violado.
Monitores PSI versus sinais de pressão vm
Como os sinais vmpressure
(gerados pelo kernel para detecção de pressão de memória e usados por lmkd
) geralmente incluem vários falsos positivos, lmkd
deve realizar a filtragem para determinar se a memória está sob pressão real. Isso resulta em ativações desnecessárias lmkd
e no uso de recursos computacionais adicionais. O uso de monitores PSI resulta em uma detecção de pressão de memória mais precisa e minimiza a sobrecarga de filtragem.
Use monitores PSI
Para usar monitores PSI em vez de eventos vmpressure
, configure a propriedade ro.lmk.use_psi
. O padrão é true
, fazendo com que o PSI monitore o mecanismo padrão de detecção de pressão de memória para lmkd
. Como os monitores PSI requerem suporte de kernel, o kernel deve incluir os patches de backport PSI e ser compilado com suporte PSI habilitado ( CONFIG_PSI=y
).
Desvantagens do driver LMK no kernel
O Android descontinua o driver LMK devido a vários problemas, incluindo:
- Dispositivos com pouca RAM tiveram que ser ajustados agressivamente e, mesmo assim, teriam um desempenho ruim em cargas de trabalho com cache de página ativo apoiado por arquivos grandes. O mau desempenho resultou em surras e nenhuma morte.
- O driver do kernel LMK dependia de limites de memória livre, sem escalonamento baseado na pressão da memória.
- Devido à rigidez do design, os parceiros frequentemente personalizavam o driver para que funcionasse em seus dispositivos.
- O driver LMK conectou-se à API do redutor de placa, que não foi projetada para operações pesadas, como procurar alvos e matá-los, o que retardava o processo
vmscan
.
Espaço do usuário lmkd
O espaço do usuário lmkd
implementa a mesma funcionalidade do driver no kernel, mas usa mecanismos de kernel existentes para detectar e estimar a pressão de memória. Esses mecanismos incluem o uso de eventos vmpressure
gerados pelo kernel ou monitores de informações de sobretensão de pressão (PSI) para obter notificações sobre níveis de pressão de memória e o uso de recursos de cgroup de memória para limitar os recursos de memória alocados para cada processo com base na importância do processo.
Use o espaço do usuário lmkd no Android 10
No Android 9 e versões posteriores, o userspace lmkd
será ativado se um driver LMK no kernel não for detectado. Como o espaço de usuário lmkd
requer suporte do kernel para cgroups de memória, o kernel deve ser compilado com as seguintes definições de configuração:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
Estratégias de matar
O Userspace lmkd
oferece suporte a estratégias de eliminação baseadas em eventos vmpressure
ou monitores PSI, sua gravidade e outras dicas, como utilização de swap. As estratégias de eliminação diferem entre dispositivos com pouca memória e dispositivos de alto desempenho:
- Em dispositivos com pouca memória, o sistema deve tolerar maior pressão de memória como modo normal de operação.
- Em dispositivos de alto desempenho, a pressão da memória deve ser vista como uma situação anormal e corrigida antes que afete o desempenho geral.
Você pode configurar a estratégia kill usando a propriedade ro.config.low_ram
. Para obter detalhes, consulte Configuração de memória RAM baixa .
O Userspace lmkd
também oferece suporte a um modo legado no qual ele toma decisões de eliminação usando as mesmas estratégias do driver LMK no kernel (ou seja, memória livre e limites de cache de arquivo). Para ativar o modo legado, configure a propriedade ro.lmk.use_minfree_levels
como true
.
Configurar o lmkd
Configure lmkd
para um dispositivo específico usando as propriedades a seguir.
Propriedade | Usar | Padrão |
---|---|---|
ro.config.low_ram | Especifique se o dispositivo é um dispositivo com pouca RAM ou de alto desempenho. | false |
ro.lmk.use_psi | Use monitores PSI (em vez de eventos vmpressure ). | true |
ro.lmk.use_minfree_levels | Use memória livre e limites de cache de arquivo para tomar decisões de eliminação de processos (ou seja, corresponder à funcionalidade do driver LMK no kernel). | false |
ro.lmk.low | A pontuação oom_adj mínima para processos elegíveis para serem eliminados em baixo nível vmpressure . | 1001 (desabilitado) |
ro.lmk.medium | A pontuação oom_adj mínima para processos elegíveis para serem eliminados no nível médio vmpressure . | 800 (serviços armazenados em cache ou não essenciais) |
ro.lmk.critical | A pontuação oom_adj mínima para processos elegíveis para serem eliminados no nível crítico vmpressure . | 0 (qualquer processo) |
ro.lmk.critical_upgrade | Habilite a atualização para o nível crítico. | false |
ro.lmk.upgrade_pressure | O mem_pressure máximo no qual o nível é atualizado porque o sistema está trocando demais. | 100 (desabilitado) |
ro.lmk.downgrade_pressure | O mem_pressure mínimo no qual um evento vmpressure é ignorado porque ainda há memória livre suficiente disponível. | 100 (desabilitado) |
ro.lmk.kill_heaviest_task | Elimine a tarefa elegível mais pesada (melhor decisão) versus qualquer tarefa elegível (decisão rápida). | true |
ro.lmk.kill_timeout_ms | Duração em milissegundos após uma morte, quando nenhuma morte adicional será realizada. | 0 (desabilitado) |
ro.lmk.debug | Ative os logs de depuração lmkd . | false |
Exemplo de configuração do dispositivo:
PRODUCT_PROPERTY_OVERRIDES += \
ro.lmk.low=1001 \
ro.lmk.medium=800 \
ro.lmk.critical=0 \
ro.lmk.critical_upgrade=false \
ro.lmk.upgrade_pressure=100 \
ro.lmk.downgrade_pressure=100 \
ro.lmk.kill_heaviest_task=true
Espaço do usuário lmkd no Android 11
O Android 11 melhora o lmkd
ao introduzir uma nova estratégia de matar. A estratégia de eliminação usa um mecanismo PSI para detecção de pressão de memória introduzido no Android 10. lmkd
no Android 11 leva em conta os níveis de uso de recursos de memória e o esgotamento para evitar a falta de memória e a degradação do desempenho. Essa estratégia de matar substitui as estratégias anteriores e pode ser usada em dispositivos de alto desempenho e com pouca RAM (Android Go).
Requisitos do kernel
Para dispositivos Android 11, lmkd
requer os seguintes recursos de kernel:
- Incluir patches PSI e ativar PSI (backports disponíveis nos kernels comuns do Android 4.9, 4.14 e 4.19).
- Inclui patches de suporte PIDFD (backports disponíveis nos kernels comuns do Android 4.9, 4.14 e 4.19).
- Para dispositivos com pouca RAM, inclua cgroups de memória.
O kernel deve ser compilado com as seguintes configurações:
CONFIG_PSI=y
Configurar lmkd no Android 11
A estratégia de eliminação de memória no Android 11 oferece suporte aos botões de ajuste e padrões listados abaixo. Esses recursos funcionam em dispositivos de alto desempenho e com pouca RAM.
Propriedade | Usar | Padrão | |
---|---|---|---|
Alta performance | RAM baixa | ||
ro.lmk.psi_partial_stall_ms | O limite de travamento parcial do PSI, em milissegundos, para acionar a notificação de pouca memória. Se o dispositivo receber notificações de pressão de memória tarde demais, diminua esse valor para acionar notificações mais cedo. Se as notificações de pressão de memória forem acionadas desnecessariamente, aumente esse valor para tornar o dispositivo menos sensível a ruídos. | 70 | 200 |
ro.lmk.psi_complete_stall_ms | O limite completo de paralisação do PSI, em milissegundos, para acionar notificações críticas de memória. Se o dispositivo receber notificações críticas de pressão de memória tarde demais, diminua esse valor para acionar notificações mais cedo. Se notificações críticas de pressão de memória forem acionadas desnecessariamente, aumente esse valor para tornar o dispositivo menos sensível a ruídos. | 700 | |
ro.lmk.thrashing_limit | A quantidade máxima de refaults do conjunto de trabalho como uma porcentagem do tamanho total do pagecache com suporte de arquivo. Refaults do conjunto de trabalho acima desse valor significam que o sistema está sobrecarregando seu pagecache. Se o desempenho do dispositivo for afetado durante a pressão da memória, diminua o valor para limitar o desgaste. Se o desempenho do dispositivo for interrompido desnecessariamente por motivos de surra, aumente o valor para permitir mais surra. | 100 | 30 |
ro.lmk.thrashing_limit_decay | A redução do limite de thrashing expressa como uma porcentagem do limite original usado para diminuir o limite quando o sistema não se recupera, mesmo após uma eliminação. Se a surra contínua produzir mortes desnecessárias, diminua o valor. Se a resposta à surra contínua após uma morte for muito lenta, aumente o valor. | 10 | 50 |
ro.lmk.swap_util_max | A quantidade máxima de memória trocada como uma porcentagem do total de memória trocável. Quando a memória trocada ultrapassa esse limite, significa que o sistema trocou a maior parte de sua memória trocável e ainda está sob pressão. Isso pode acontecer quando as alocações não trocáveis estão gerando pressão de memória que não pode ser aliviada pela troca porque a maior parte da memória trocável já foi trocada. O valor padrão é 100, o que desativa efetivamente essa verificação. Se o desempenho do dispositivo for afetado durante a pressão da memória enquanto a utilização de swap estiver alta e o nível de swap livre não estiver caindo para ro.lmk.swap_free_low_percentage , diminua o valor para limitar a utilização de swap. | 100 | 100 |
Os botões de ajuste antigos a seguir também funcionam com a nova estratégia de matar.
Propriedade | Usar | Padrão | |
---|---|---|---|
Alta performance | RAM baixa | ||
ro.lmk.swap_free_low_percentage | O nível de swap livre como porcentagem do espaço de swap total. `lmkd` usa este valor como um limite para quando considerar o sistema como sem espaço de troca. Se `lmkd` matar enquanto houver muito espaço na troca, diminua a porcentagem. Se as mortes do `lmkd` acontecerem tarde demais, permitindo que as mortes do OOM aconteçam, aumente a porcentagem. | 20 | 10 |
ro.lmk.debug | Isso ativa os logs de depuração `lmkd`. Habilite a depuração durante o ajuste. | false |