O processo do daemon do Android Low Memory Killer (lmkd
) monitora o estado
de memória de um sistema Android em execução e reage à alta pressão de memória encerrando
os processos menos essenciais para manter o desempenho do sistema em níveis
aceitáveis.
Sobre a pressão de memória
Um sistema Android que executa vários processos em paralelo pode encontrar situações em que a memória do sistema está esgotada e 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) restringindo ou encerrando processos sem importância, solicitando processos para liberar recursos não críticos armazenados em cache e assim por diante.
Historicamente, o Android monitorava a pressão da memória do sistema usando um driver
de LMK 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 lmkd
do espaço do usuário executa tarefas de monitoramento de memória e
de eliminação de processos.
Informações sobre compressão de pressão
O Android 10 e versões mais recentes oferecem suporte a um novo modo lmkd
que
usa monitores de informação de pouca pressão (PSI, na sigla em inglês) do kernel para detecção de pressão
da memória. O conjunto de patches do PSI no kernel upstream (retornado para kernels 4.9 e 4.14)
mede o tempo que as tarefas são atrasadas devido a
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 do usuário
privilegiados (como lmkd
) especifiquem limites para esses atrasos e
se inscrevam em eventos do kernel quando um limite é violado.
Monitores PSI x sinais de vmpressure
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,
o lmkd
precisa realizar a filtragem para determinar se a memória está sob pressão real.
Isso resulta em ativações lmkd
desnecessárias e no uso de outros
recursos computacionais. O uso de monitores de PSI resulta em uma detecção de pressão
de memória mais precisa e minimiza a sobrecarga de filtragem.
Usar monitores de 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 da memória para lmkd
. Como os monitores de PSI
exigem suporte ao kernel, o kernel precisa incluir os patches de backport do PSI e ser
compilado com o suporte ao PSI ativado (CONFIG_PSI=y
).
Desvantagens do driver LMK no kernel
O Android descontinua o driver LMK devido a vários problemas, incluindo:
- Os dispositivos com pouca RAM precisavam ser ajustados de forma agressiva e, mesmo assim, apresentavam um desempenho ruim em cargas de trabalho com um grande cache de página ativo com suporte a arquivos. O desempenho ruim resultou em sobrecarga e nenhuma interrupção.
- O driver do kernel LMK dependia de limites de memória livre, sem dimensionamento baseado na pressão de memória.
- Devido à rigidez do design, os parceiros geralmente personalizavam o driver para que ele funcionasse nos dispositivos.
- O driver do LMK foi conectado à API de redutor de laje, que não foi
projetada para operações pesadas, como pesquisar e eliminar
alvos, o que atrasava o processo
vmscan
.
lmkd do espaço do usuário
O lmkd
do espaço do usuário implementa a mesma funcionalidade do driver no kernel,
mas usa mecanismos do kernel para detectar e estimar a pressão da memória. Esses
mecanismos incluem o uso de eventos vmpressure
gerados pelo kernel ou de monitores de informações
de bloqueio de pressão (PSI, na sigla em inglês) para receber 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.
Usar o lmkd do espaço do usuário no Android 10
No Android 9 e versões mais recentes, o espaço do usuário lmkd
será ativado se
um driver LMK no kernel não for detectado. Como o lmkd
do espaço do usuário
exige suporte do kernel para cgroups de memória, o kernel precisa ser compilado com as
seguintes configurações:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
Estratégias de eliminação
O espaço do usuário lmkd
é compatível com estratégias de destruição baseadas em eventos vmpressure
ou monitores
PSI, na gravidade deles e em outras dicas, como utilização de troca. As estratégias de
desligamento são diferentes entre dispositivos de pouca memória e de alto desempenho:
- Em dispositivos com pouca memória, o sistema precisa tolerar uma pressão de memória mais alta como um modo normal de operação.
- Em dispositivos de alto desempenho, a pressão da memória precisa ser considerada uma situação anormal e corrigida antes que ela afete o desempenho geral.
É possível configurar a estratégia de eliminação usando a propriedade ro.config.low_ram
. Saiba
mais em Configuração de RAM
baixa.
O lmkd
do espaço do usuário também oferece suporte a um modo legado em que ele toma decisões de eliminação
usando as mesmas estratégias do driver LMK no kernel, ou seja, limites de
memória livre e cache de arquivos. Para ativar o modo legado, defina a
propriedade ro.lmk.use_minfree_levels
como true
.
Configurar lmkd
Configure o lmkd
para um dispositivo específico usando as propriedades abaixo.
Propriedade | Uso | Padrão |
---|---|---|
ro.config.low_ram
|
Especifique se o dispositivo tem pouca RAM ou é de alto desempenho. | false
|
ro.lmk.use_psi |
Use monitores de PSI (em vez de eventos vmpressure ). |
true |
ro.lmk.use_minfree_levels
|
Use os limites de memória livre e de cache de arquivos para tomar decisões de encerramento de processos, ou seja, corresponda à funcionalidade do driver LMK no kernel. | false
|
ro.lmk.low
|
A pontuação mínima oom_adj para processos qualificados para
serem encerrados no nível vmpressure baixo.
|
1001 (desativado) |
ro.lmk.medium
|
A pontuação mínima de oom_adj para processos qualificados para encerramento
no nível médio de vmpressure .
|
800 (serviços armazenados em cache ou não essenciais) |
ro.lmk.critical
|
A pontuação mínima de oom_adj para processos qualificados para encerramento
no nível crítico de vmpressure .
|
0 (qualquer processo) |
ro.lmk.critical_upgrade
|
Ativar upgrade para o nível crítico. | false
|
ro.lmk.upgrade_pressure
|
O mem_pressure máximo em que o nível é atualizado
porque o sistema está fazendo muitas trocas.
|
100 (desativado) |
ro.lmk.downgrade_pressure
|
O mem_pressure mínimo em que um evento vmpressure
é ignorado porque ainda há memória disponível suficiente.
|
100 (desativado) |
ro.lmk.kill_heaviest_task
|
Elimine a tarefa qualificada mais pesada (melhor decisão) em vez de qualquer tarefa qualificada (decisão rápida). | false
|
ro.lmk.kill_timeout_ms
|
Duração em milissegundos após uma eliminação quando nenhuma outra eliminação será feita. | 0 (desativado) |
ro.lmk.debug
|
Ative os registros de depuração do 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
lmkd do espaço do usuário no Android 11
O Android 11 melhora o lmkd
com a introdução de uma nova
estratégia de eliminação. A estratégia de eliminação usa um mecanismo PSI para detecção de pressão da memória introduzido no Android 10. O lmkd
no
Android 11 considera os níveis de uso de recursos de memória
e a sobrecarga para evitar a privação de memória e a degradação do desempenho.
Essa estratégia de eliminação substitui as anteriores e pode ser usada em
dispositivos de alto desempenho e com pouca memória RAM (Android Go).
Requisitos do kernel
Para dispositivos Android 11, o lmkd
requer os seguintes recursos do kernel:
- Inclua patches de PSI e ative o PSI (backports disponíveis nos kernels comuns do Android 4.9, 4.14 e 4.19).
- Incluir patches de compatibilidade com PIDFD, backports disponíveis nos kernels comuns do Android 4.9, 4.14 e 4.19.
- Para dispositivos com pouca memória RAM, inclua grupos de controle de memória.
O kernel precisa ser compilado com as seguintes configurações:
CONFIG_PSI=y
Configurar o lmkd no Android 11
A estratégia de eliminação de memória no Android 11 oferece suporte aos controles de ajuste e padrões listados abaixo. Esses recursos funcionam em dispositivos de alto desempenho e com pouca memória RAM.
Propriedade | Uso | Padrão | |
---|---|---|---|
Alto desempenho | RAM baixa | ||
ro.lmk.psi_partial_stall_ms |
O limite de paralisação parcial do PSI, em milissegundos, para acionar a notificação de memória baixa. Se o dispositivo receber notificações de pressão de memória tarde demais, diminua esse valor para acionar notificações mais antigas. Se as notificações de pressão de memória forem acionadas desnecessariamente, aumente esse valor para tornar o dispositivo menos sensível ao ruído. | 70 |
200 |
ro.lmk.psi_complete_stall_ms |
O limite completo de inatividade de PSI, em milissegundos, para acionar notificações de memória críticas. Se o dispositivo receber notificações de pressão de memória tarde demais, diminua esse valor para acionar notificações mais antigas. Se as notificações de pressão crítica 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 revisões de conjunto de trabalho como uma porcentagem do tamanho total da página de cache de arquivos. As revisões de conjunto de trabalho acima desse valor significam que o sistema está sendo considerado como um cache de página. Se o desempenho do dispositivo for afetado durante a pressão da memória, diminua o valor para limitar o thrashing. Se o desempenho do dispositivo for encerrado desnecessariamente por motivos de thrashing, aumente o valor para permitir mais thrashing. | 100 |
30 |
ro.lmk.thrashing_limit_decay |
O declínio do limite de sobrecarga expresso como uma porcentagem do limite original usado para diminuir o limite quando o sistema não se recupera, mesmo após uma interrupção. Se o uso excessivo contínuo produzir mortes desnecessárias, diminua o valor. Se a resposta à sobrecarga contínua após uma interrupção for muito lenta, aumente o valor. | 10 |
50 |
ro.lmk.swap_util_max |
A quantidade máxima de memória trocada como uma porcentagem da memória total
trocável. Quando a memória trocada aumenta acima desse limite, significa que o
sistema trocou a maior parte da memória intercambiável e ainda está sob pressão.
Isso pode acontecer quando alocações não trocáveis geram pressão de memória
que não pode ser aliviada pela troca, porque a maioria da memória
trocável já foi trocada. O valor padrão é 100, o que desativa essa verificação. Se o desempenho do dispositivo for afetado durante
a pressão da memória enquanto a utilização de troca estiver alta e o nível de troca livre
não estiver caindo para ro.lmk.swap_free_low_percentage , diminua
o valor para limitar a utilização de troca. |
100 |
100 |
Os botões de ajuste antigos a seguir também funcionam com a nova estratégia de desativação.
Propriedade | Uso | Padrão | |
---|---|---|---|
Alto desempenho | Pouca RAM | ||
ro.lmk.swap_free_low_percentage |
O nível de troca livre como uma porcentagem do espaço de troca total. "lmkd" usa esse valor como um limite para considerar o sistema como um espaço de troca com falta. Se o `lmkd` for encerrado quando houver muito espaço em troca, diminua a porcentagem. Se o `lmkd` for encerrado muito tarde, permitindo que o encerramento por falta de memória aconteça, aumente a porcentagem. | 20 |
10 |
ro.lmk.debug |
Isso ativa os registros de depuração "lmkd". Ative a depuração durante o ajuste. | false |