O Android 17 e versões mais recentes são compatíveis com o daemon de gerenciamento de memória
(mmd), um daemon do sistema que lida com a configuração do daemon, os ajustes e as tarefas contínuas de troca ou manutenção do ZRAM.
Contexto
Antes da introdução do mmd, as configurações de ZRAM do Android eram
fragmentadas e ofereciam personalização limitada. O mmd resolve isso centralizando o gerenciamento do ZRAM, permitindo uma lógica de configuração mais sofisticada e simplificando a adição de novos recursos e melhorias arquitetônicas.
O mmd também estabelece uma separação clara de responsabilidades entre o processo system_server baseado em Java e a troca ou o gerenciamento de memória no nível do kernel.
Arquitetura e gerenciamento de ZRAM
Quando a inicialização é concluída (ou seja, quando sys.boot_completed=1), o mmd_setup tenta
configurar o ZRAM com os parâmetros especificados. Depois que a configuração do ZRAM for concluída, o
sistema vai ativar o serviço mmd, que lida com tarefas de manutenção contínuas.
Com o projeto mmd, as operações de manutenção são iniciadas em
system_server enviando solicitações do Binder para mmd usando a interface IMmd.
O mmd processa as tarefas de manutenção de execução de writeback de ZRAM,
recompressão e writeback por processo com base no próprio mecanismo
de política interna. O agendamento de ActivityManagerService e as políticas de manutenção do ZRAM podem ser configurados usando propriedades do sistema.
Integração do servidor do sistema (system_server)
O processo system_server baseado em Java determina quando mmd é invocado. O
processo separa as limpezas de manutenção globais das otimizações de memória
específicas por app.
Manutenção normal de pós-processamento
A manutenção global do ZRAM é feita pelo ActivityManagerService usando
com.android.server.memory.ZramMaintenance.

Figura 1. Fluxo de programação de manutenção do ZRAM.
- Mecanismo de programação:
ZramMaintenanceregistra um trabalho periódico em segundo plano com oJobSchedulerdo Android. - Restrições de job:para evitar renderização lenta na interface do usuário em primeiro plano ou disputa de CPU, o job é configurado explicitamente com
setRequiresDeviceIdle(true)esetRequiresBatteryNotLow(true). - Acionamento do binder:quando o programador dispara
onStartJob(),system_serverinvocammd.doZramMaintenanceAsync(). Essa é uma chamada assíncrona do Binder unidirecional. Osystem_servernão bloqueia a espera pela conclusão das varreduras de manutenção. Ommdcoloca isso em uma linha de execução de worker em segundo plano para realizar a recompressão e o writeback sequencialmente.
Writeback por processo
A remoção direcionada de memória por processo é gerenciada pelo ActivityManagerService usando
com.android.server.am.CachedAppOptimizer.

Figura 2: fluxo de gravação de retorno por processo do mmd.
Quando um processo passa para um estado armazenado em cache em segundo plano, o ActivityManager realiza a compactação da memória. Se um encerramento por falta de memória do processo for visível para o usuário, ou seja, o processo hospeda uma atividade, e se o writeback por processo do ZRAM reduzir o consumo de memória do processo a quase zero, o sistema vai seguir estas etapas:
- Após a compactação,
CachedAppOptimizerenvia uma mensagem atrasada (ZRAM_WRITEBACK_MSG) ao gerenciador de compactação interna (atrasada emmZramWritebackWaitSeconds). - Quando o atraso expira, o ActivityManager abre um descritor de arquivo de processo seguro
pidfd. - O servidor do sistema chama
mmd.asyncWritebackProcessZramMemory(pfd, callback). mmdexecuta o ioctl de writeback por processo e gera relatórios usandoIMmdProcessWritebackCallback. Se for bem-sucedido, o ActivityManager vai sinalizar o registro do processo (setIsZramWrittenBack(app, true)) para aumentar ooom_score_adjdo processo e registrar métricas emFrameworkStatsLog.ZRAM_WRITEBACK_EVENT.
Pré-busca por processo
Quando um usuário reinicia um app armazenado em cache anteriormente (descongelado devido a
UNFREEZE_REASON_ACTIVITY), o ActivityManager minimiza a latência de inicialização
do app causada por falhas de página importantes do armazenamento de apoio:
CachedAppOptimizerintercepta o evento de descongelamento e invocaprefetchZram(app).- O servidor do sistema envia o
pidfddo app pelo Binder usandommd.asyncPrefetchProcessZramMemory(pfd). Ommdemite o ioctlZRAM_ANDROID_IOC_PROCESS_PREFETCH, instruindo o kernel a fazer a pré-busca assíncrona das páginas trocadas de volta para a RAM enquanto a linha de execução principal da interface do app está sendo inicializada.
Visão geral das tarefas de manutenção e pós-processamento
Esta seção descreve as operações de manutenção em segundo plano e
as tarefas de pós-processamento que o mmd executa para otimizar o espaço de troca e a memória do sistema.
Manutenção no mmd
Em mmd, manutenção se refere a varreduras de manutenção programadas em segundo plano
que otimizam o uso do espaço de troca e da memória física sem afetar
o desempenho em primeiro plano do usuário ativo. Em vez de realizar varreduras contínuas e síncronas (que causariam ativações graves da CPU e instabilidade da interface), a manutenção é feita de forma assíncrona:
O
system_serverdispara periodicamentedoZramMaintenanceAsync()no Binder.O
mmdcoloca a solicitação em uma fila de trabalho em segundo planoLowPrioWorkItem::ZramMaintenance.Há uma única linha de execução de worker em
mmdque gerencia uma fila de alta prioridade e uma de baixa prioridade. Os itens de trabalho de alta prioridade (como pré-busca por processo) são processados primeiro e podem forçar a interrupção de itens de trabalho de baixa prioridade. A manutenção e o writeback por processo funcionam como itens de trabalho de baixa prioridade. Quando removida, a linha de execução de worker executa duas operações principais de manutenção em sequência:Recompressão ZRAM:verifica as páginas de troca atuais e recomprime as páginas inativas usando um algoritmo de compressão secundária de proporção mais alta, por exemplo,
zstd.Writeback da ZRAM:verifica páginas inativas e as remove completamente da RAM para o armazenamento flash de apoio, um dispositivo de loop de um arquivo em
/data.
Tarefas de pós-processamento na zRAM
No módulo ZRAM do kernel do Linux e na arquitetura mmd, as tarefas de pós-processamento são as transformações assíncronas aplicadas às páginas de memória depois que elas já foram trocadas pelos caminhos de recuperação padrão do kernel (kswapd ou compactação).
Quando uma página é substituída inicialmente, o sistema prioriza a velocidade: ele usa um algoritmo de compactação primário rápido (como lz4) e armazena a página compactada na RAM. No entanto, com o tempo, muitas páginas trocadas ficam inativas ou ociosas,
por exemplo, apps em cache em segundo plano que não são retomados por horas. Deixar páginas frias na zRAM rápida e levemente compactada é ineficiente.
Pipeline de pós-processamento
O mmd implementa um ciclo de vida de pós-processamento de vários estágios para otimizar essas páginas:

Figura 3. mmd ciclo de vida da página.
Etapa 1: troca inicial (compressão rápida): a memória é recuperada primeiro pelo kswapd ou pela compactação de apps. Normalmente, essa primeira recuperação é realizada usando um algoritmo de compactação rápida, como
lz4, e o conteúdo é armazenado na RAM.Etapa 2: marcação de inatividade (envelhecimento e rastreamento):
mmdacessos de rastreamento de inatividade, rastreamento de memória do kernel (CONFIG_ZRAM_TRACK_ENTRY_ACTIME) ou usa o marcador de inatividade do software para rastrear por quanto tempo as páginas ficaram sem interação.Etapa 3: pós-processamento 1: recompressão (recuperação na memória): as páginas que atingem a idade de inatividade da recompressão (
min_idle_secondsamax_idle_seconds) passam por recompressão. Ommdgrava em/sys/block/zram0/recompresspara instruir o kernel a descompactar a páginalz4e compactá-la novamente usandozstd. Isso recupera a RAM física sem causar desgaste de gravação flash.Etapa 4: pós-processamento 2: gravação de volta (remoção para armazenamento flash): se a pressão na memória continuar e as páginas atingirem a idade de inatividade de gravação de volta (normalmente 20 horas ou mais), o
mmdvai acionar a gravação de volta. Ommdgrava em/sys/block/zram0/idlee/sys/block/zram0/writebackpara desalojar a página compactada completamente da RAM para o armazenamento flash de apoio.
Configuração da ZRAM
O mmd carrega e processa as seguintes propriedades de configuração do ZRAM:
| Propriedade | Usar | Padrão |
|---|---|---|
mmd.zram.enabled |
Se a configuração do mmd ZRAM está ativada. |
false |
mmd.zram.num_devices |
O número de dispositivos ZRAM a serem configurados. Para um número N, os dispositivos zram0 a zram<N-1> precisam estar presentes antes que o sistema defina sys.boot_completed=1.
As propriedades na lista de dispositivos por ZRAM podem ser configuradas por dispositivo.
|
1 |
mmd.zram.device_priority |
Valores de prioridade a serem transmitidos ao chamar swapon. |
Não definido |
mmd.zram.comp_algorithm |
Algoritmo de compactação ZRAM. O algoritmo de compactação padrão do kernel será usado se não for especificado. | Não definido |
mmd.zram.size |
Tamanho do dispositivo zRAM em bytes ou uma porcentagem do tamanho da RAM do dispositivo, por exemplo, 75%.
|
50% |
mmd.zram.writeback.enabled |
Define se o writeback do ZRAM será ativado. | false |
mmd.zram.writeback.device_size |
O tamanho do dispositivo de gravação em bytes ou a porcentagem da partição de dados. O tamanho real do dispositivo pode ser ajustado com base no espaço disponível na partição de dados. | 1073741824 (1 GiB) |
mmd.zram.writeback.min_free_space_mib |
Espaço livre mínimo em MiB que precisa estar disponível após a configuração do dispositivo de writeback. | 1536 (1,5 GiB) |
mmd.zram.writeback.use_nr_tags_prop |
Quando true, usa o valor em
mmd.zram.writeback.nr_tags para configurar a profundidade da fila do
dispositivo de loop que faz o writeback do ZRAM. Essa é uma solução alternativa para
situações em que a política do SELinux do fornecedor não pode ser configurada para permitir
que mmd leia diretamente nr_tags do dispositivo
de bloco que faz backup de /data.
|
false |
mmd.zram.writeback.nr_tags |
Consulte mmd.zram.writeback.use_nr_tags_prop. |
Não definido |
mmd.zram.recompression.enabled |
Se o recurso de recompressão ZRAM deve ser ativado. | false |
mmd.zram.recompression.algorithm |
Algoritmo secundário de recompressão do ZRAM. | zstd |
Propriedades do dispositivo por ZRAM
Quando mmd.zram.num_devices é maior que um, propriedades específicas podem ser configuradas opcionalmente em cada dispositivo ZRAM definindo a propriedade como um valor separado por vírgulas que contém exatamente mmd.zram.num_devices elementos.
Essas propriedades incluem:
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
Descontinuação da configuração atual do ZRAM
Embora swapon_all ainda esteja disponível no Android para configurar a ZRAM e o espaço de troca
baseado em disco, mmd é a abordagem preferida para o gerenciamento da ZRAM, facilitando a
configuração e recursos avançados, como a recompactação da ZRAM.
Quando a configuração de ZRAM mmd é ativada por mmd.zram.enabled:
- A configuração do ZRAM na implementação do
swapon_allse torna uma operação nula. - As configurações atuais do ZRAM, como
config_zramWritebackno arquivo de sobreposiçãoconfig.xmle as propriedades do sistema de writebackro.zram.*, são ignoradas.
Ajustes de manutenção do ZRAM
A manutenção do ZRAM funciona sem precisar de configuração, e você pode ajustar ainda mais usando as propriedades do sistema nesta seção.
Programação de manutenção do ZRAM
Essas propriedades controlam como e quando as tarefas de manutenção do ZRAM são programadas pelo
system_server.
| Propriedade | Usar | Padrão |
|---|---|---|
mm.zram.maintenance.first_delay_seconds |
O atraso antes do início da primeira manutenção do ZRAM. | 3600 (1 hora) |
mm.zram.maintenance.periodic_delay_seconds |
O atraso entre o agendamento de manutenção subsequente do ZRAM. | 3600 (1 hora) |
mm.zram.maintenance.require_device_idle |
Se a manutenção do ZRAM só deve ser iniciada quando o dispositivo estiver inativo. | true |
mm.zram.maintenance.require_battery_not_low |
Se é necessário que a bateria não esteja fraca antes de iniciar a manutenção do ZRAM. | true |
Política de writeback do ZRAM
Os parâmetros a seguir controlam quando e qual tipo de memória é gravado no dispositivo de suporte:
| Propriedade | Usar | Padrão |
|---|---|---|
mmd.zram.writeback.backoff_seconds |
O tempo de espera desde a última operação de gravação. | 600 (10 minutos) |
mmd.zram.writeback.min_idle_seconds |
Combinado com mmd.zram.writeback.max_idle_seconds para calcular
a idade de inatividade de uma página para que ela se qualifique para gravação com base na fração de utilização
da memória. A idade ociosa calculada é interpolada exponencialmente entre os dois parâmetros para minimizar o trabalho sem pressão de memória.
|
72000 (20 horas) |
mmd.zram.writeback.max_idle_seconds |
Número máximo de segundos usados para calcular a idade da página inativa de forma dinâmica com base na utilização da memória. | 90000 (25 horas) |
mmd.zram.writeback.huge.enabled |
Define se o writeback da página HUGE será ativado. |
false |
mmd.zram.writeback.idle.enabled |
Define se o writeback da página IDLE será ativado. |
true |
mmd.zram.writeback.huge_idle.enabled |
Define se o writeback da página HUGE_IDLE será ativado. |
true |
mmd.zram.writeback.min_bytes |
Número mínimo de bytes a serem gravados em uma rodada de gravação ociosa. | 5242880 (5 MiB) |
mmd.zram.writeback.max_bytes |
Número máximo de bytes a serem gravados em uma rodada de gravação inativa. | 314572800 (300 MiB) |
mmd.zram.writeback.max_bytes_per_day |
Número máximo de bytes a serem gravados em um período de 24 horas. | 25769803776 (24 GiB) |
mmd.zram.writeback.limit.enabled |
Define se a contabilização do limite de orçamento de gravação diária será ativada. | true |
Política de recompressão do ZRAM
Os parâmetros a seguir controlam quando e qual tipo de memória é recompactado:
| Propriedade | Usar | Padrão |
|---|---|---|
mmd.zram.recompression.backoff_seconds |
O tempo de espera desde a última recompressão. | 1800 (30 minutos) |
mmd.zram.recompression.min_idle_seconds |
Combinado com mmd.zram.recompression.max_idle_seconds para calcular a idade de inatividade de uma página e determinar se ela está qualificada para recompressão com base na fração de utilização da memória. A idade ociosa calculada é interpolada exponencialmente entre os dois parâmetros para minimizar o trabalho sem pressão de memória.
|
7200 (2 horas) |
mmd.zram.recompression.max_idle_seconds |
Número máximo de segundos usados para calcular dinamicamente a idade da página inativa. | 14400 (4 horas) |
mmd.zram.recompression.threshold_bytes |
Tamanho mínimo em bytes das páginas ZRAM consideradas para recompressão. | 1024 (1 KiB) |
mmd.zram.recompression.huge.enabled |
Se a recompactação da página HUGE precisa ser ativada. |
true |
mmd.zram.recompression.idle.enabled |
Se a recompactação da página IDLE precisa ser ativada. |
true |
mmd.zram.recompression.huge_idle.enabled |
Se a recompactação da página HUGE_IDLE precisa ser ativada. |
true |
Rastreamento de páginas inativas da zRAM
mmd A manutenção da zRAM marca as páginas como inativas com base no tempo decorrido desde o último acesso. Esse recurso exige que as configurações de kernel CONFIG_ZRAM_TRACK_ENTRY_ACTIME ou CONFIG_ZRAM_MEMORY_TRACKING estejam ativadas. CONFIG_ZRAM_TRACK_ENTRY_ACTIME é ativado por
padrão nos kernels do GKI 6.18 e mais recentes. Em kernels anteriores, ele tem sobrecarga de memória e não é ativado por padrão.
Se a configuração do kernel não estiver ativada, a manutenção da mmd ZRAM vai usar uma lógica de substituição de software para rastrear páginas inativas da ZRAM:
Marque todas as páginas da zRAM como inativas quando o
mmdfor iniciado.Pule as próximas manutenções do ZRAM até que o período de espera necessário tenha passado.
Retorno de gravação da zRAM ou recompilação de páginas inativas. Se houver páginas inativas restantes devido a limites de gravação, o
mmdcontinuará gravando páginas na próxima manutenção sem marcar novas páginas como inativas (pulando a etapa 4).Se todas as páginas inativas forem gravadas novamente, marque todas as páginas da ZRAM como inativas de novo e volte para a etapa 2. Se o writeback da ZRAM estiver desativado, o
mmdvai marcar todas as páginas da ZRAM como inativas quando a recompactação da ZRAM acontecer após a duração de inatividade da recompactação.
Orientações para solução de problemas e validação
Siga as etapas de validação e os procedimentos de solução de problemas abaixo para verificar e diagnosticar operações de mmd e ZRAM.
Validar a configuração do ZRAM
Para verificar se mmd configurou o ZRAM com sucesso durante a inicialização:
Verifique o algoritmo de compactação ativo e o tamanho do disco:
cat /sys/block/zram0/comp_algorithm cat /sys/block/zram0/disksizeVerifique as propriedades do sistema
mmde o estado do serviço em execução:getprop | grep mmd.zram dumpsys -l | grep mmd
Validar a manutenção e o writeback do ZRAM
Verifique se as tarefas de manutenção de writeback e recompressão do ZRAM estão funcionando:
Verifique o status do dispositivo de bloco de suporte:
cat /sys/block/zram0/bd_statMonitore
/sys/block/zram0/mm_statpara verificar a eficiência da recompressão. As mudanças nos tamanhos dos dados compactados vão aparecer após os ciclos de manutenção.
Validar o writeback por processo
O seguinte pode ser usado para validar se o writeback por processo está funcionando:
- Verifique
adb logcat -s mmdpara ver registros de gravação bem-sucedidos ou diagnósticos de falha.
Problemas comuns e diagnósticos
Estas são situações de erro comuns que o usuário pode encontrar:
WritebackDailyLimitExceeded:esse erro indica que a cota demmd.zram.writeback.max_bytes_per_dayfoi atingida. Quando isso acontece, ommdpausa o writeback inativo até que a janela de 24 horas avance.Process prefetch or writeback failed:esse erro pode ser observado no logcat quando um ioctl falha. Algumas causas comuns:EBADFouESRCH: o processo de destino foi encerrado antes quemmdpudesse enviar opidfdao kernel.ENOSPC: a partição de armazenamento de suporte está cheia ou a fila do dispositivo de loop está esgotada.
- ZRAM não configurada:se o
mmdnão conseguir configurar a ZRAM na inicialização, talvez seja porque scripts de inicialização legados doswapon_allou do fornecedor bloquearam o/dev/block/zram0antes que ommdpudesse ser executado.