Android 17 e versioni successive supportano il daemon di gestione della memoria
(mmd), un daemon di sistema, che gestisce la configurazione, i parametri regolabili e le attività di manutenzione
di swap o ZRAM in corso.
Sfondo
Prima dell'introduzione di mmd, le configurazioni ZRAM di Android erano
frammentate e offrivano una personalizzazione limitata. mmd risolve questo problema
centralizzando la gestione di ZRAM, consentendo una logica di configurazione più sofisticata
e semplificando l'aggiunta di nuove funzionalità e miglioramenti dell'architettura.
mmd stabilisce inoltre una chiara separazione delle responsabilità tra il processo system_server basato su Java e la gestione della memoria o dello swap a livello di kernel.
Architettura e gestione di ZRAM
Al termine dell'avvio (ovvero quando sys.boot_completed=1), mmd_setup tenta
di configurare ZRAM con i parametri specificati. Al termine della configurazione di ZRAM, il sistema attiva il servizio mmd, che gestisce le attività di manutenzione in corso.
Con il progetto mmd, le operazioni di manutenzione vengono avviate da
system_server inviando richieste Binder a mmd utilizzando l'interfaccia IMmd.
mmd gestisce le attività di manutenzione di esecuzione del writeback ZRAM,
ricompressione e writeback per processo in base al proprio motore di criteri
interno. Sia la pianificazione da ActivityManagerService sia le norme di manutenzione ZRAM possono essere configurate utilizzando le proprietà di sistema.
Integrazione del server di sistema (system_server)
Il processo system_server basato su Java determina quando viene richiamato mmd. La
procedura separa le pulizie di manutenzione globali dalle ottimizzazioni mirate della memoria per app.
Manutenzione normale della post-elaborazione
La manutenzione globale di ZRAM è gestita da ActivityManagerService utilizzando
com.android.server.memory.ZramMaintenance.

Figura 1. Flusso di pianificazione della manutenzione di ZRAM.
- Motore di pianificazione:
ZramMaintenanceregistra un'attività periodica in background conJobSchedulerdi Android. - Vincoli del job:per evitare problemi di stuttering dell'interfaccia utente in primo piano o contese della CPU, il job è configurato in modo esplicito con
setRequiresDeviceIdle(true)esetRequiresBatteryNotLow(true). - Attivazione del binder:quando lo scheduler attiva
onStartJob(),system_serverrichiamammd.doZramMaintenanceAsync(). Si tratta di una chiamata Binder asincrona unidirezionale;system_servernon blocca l'attesa del completamento delle operazioni di manutenzione.mmdlo mette in coda in un thread di lavoro in background per eseguire la ricompressione e la riscrittura in sequenza.
Writeback per processo
L'eliminazione mirata della memoria per processo viene gestita da ActivityManagerService utilizzando
com.android.server.am.CachedAppOptimizer.

Figura 2. Flusso di writeback per processo di mmd.
Quando un processo passa a uno stato memorizzato nella cache in background, ActivityManager esegue la compattazione della memoria. Se un'interruzione per memoria insufficiente del processo fosse visibile all'utente, ovvero se il processo ospita un'attività e se il writeback per processo di ZRAM portasse il footprint della memoria del processo quasi a zero, il sistema esegue i seguenti passaggi:
- Dopo la compattazione,
CachedAppOptimizerpubblica un messaggio ritardato (ZRAM_WRITEBACK_MSG) al suo gestore di compattazione interno (ritardato dimZramWritebackWaitSeconds). - Quando il ritardo scade, ActivityManager apre un descrittore di file di processo sicuro
pidfd. - Il server di sistema chiama
mmd.asyncWritebackProcessZramMemory(pfd, callback). mmdesegue l'ioctl di writeback per processo e invia una risposta utilizzandoIMmdProcessWritebackCallback. Se l'operazione va a buon fine, ActivityManager contrassegna il record del processo (setIsZramWrittenBack(app, true)) per aumentare iloom_score_adjdel processo e registra le metriche inFrameworkStatsLog.ZRAM_WRITEBACK_EVENT.
Prefetch per processo
Quando un utente riavvia un'app precedentemente memorizzata nella cache (sbloccata a causa di
UNFREEZE_REASON_ACTIVITY), ActivityManager riduce al minimo la latenza di avvio dell'app
causata da errori di pagina gravi dall'archiviazione di backup:
CachedAppOptimizerintercetta l'evento di riattivazione e richiamaprefetchZram(app).- Il server di sistema invia l'intent
pidfddell'app tramite Binder utilizzandommd.asyncPrefetchProcessZramMemory(pfd).mmdemette l'ioctlZRAM_ANDROID_IOC_PROCESS_PREFETCH, istruendo il kernel a precaricare in modo asincrono le pagine scambiate nella RAM mentre il thread dell'interfaccia utente principale dell'app è in fase di inizializzazione.
Panoramica delle attività di manutenzione e post-elaborazione
Questa sezione descrive le operazioni di manutenzione in background e
le attività di post-elaborazione eseguite da mmd per ottimizzare lo spazio di swap e la memoria di sistema.
Manutenzione in mmd
In mmd, la manutenzione si riferisce alle operazioni di manutenzione pianificate in background
che ottimizzano l'utilizzo dello spazio di swap e della memoria fisica senza influire
sulle prestazioni in primo piano degli utenti attivi. Anziché eseguire scansioni continue e sincrone (che causerebbero riattivazioni della CPU e problemi di UI), la manutenzione viene eseguita in modo asincrono:
system_serverattiva periodicamentedoZramMaintenanceAsync()in Binder.mmdinserisce la richiesta in una coda di lavoro in backgroundLowPrioWorkItem::ZramMaintenance.In
mmdè presente un singolo thread worker che gestisce sia una coda a priorità elevata sia una coda a priorità bassa. Gli elementi di lavoro ad alta priorità (come il prefetch per processo) vengono elaborati per primi e possono avere la precedenza sugli elementi di lavoro a bassa priorità. La manutenzione e il writeback per processo funzionano come elementi di lavoro a bassa priorità. Quando viene estratto, il thread di lavoro esegue in sequenza due operazioni di manutenzione principali:Ricompressione ZRAM:esamina le pagine di swap esistenti e ricomprime le pagine inattive utilizzando un algoritmo di compressione secondaria con un rapporto più elevato, ad esempio
zstd.Scrittura differita ZRAM: esegue la scansione delle pagine inattive e le rimuove completamente dalla RAM per eseguire il backup dello spazio di archiviazione flash di un dispositivo loop da un file su
/data.
Attività di post-elaborazione in ZRAM
Nel modulo ZRAM del kernel Linux e nell'architettura mmd, le attività di post-elaborazione sono le trasformazioni asincrone applicate alle pagine di memoria dopo che sono già state scambiate dai percorsi di recupero standard del kernel (kswapd o compattazione).
Quando una pagina viene inizialmente sostituita, il sistema dà la priorità alla velocità: utilizza un
algoritmo di compressione primario veloce (come lz4) e memorizza la pagina compressa
nella RAM. Tuttavia, nel tempo, molte pagine di swap diventano fredde o inattive,
ad esempio le app memorizzate nella cache in background che non vengono riprese per ore. Lasciare le pagine fredde nella ZRAM veloce e leggermente compressa è inefficiente.
Pipeline di post-elaborazione
mmd implementa un ciclo di vita di post-elaborazione multifase per ottimizzare queste pagine:

Figura 3. mmd ciclo di vita della pagina.
Fase 1: sostituzione iniziale (compressione rapida): la memoria viene recuperata tramite kswapd o la compattazione delle app. In genere, questo primo recupero viene eseguito utilizzando un algoritmo di compressione rapida come
lz4e i contenuti vengono memorizzati nella RAM.Fase 2: contrassegno di inattività (invecchiamento e monitoraggio):
mmdil monitoraggio dell'inattività accede al monitoraggio della memoria del kernel (CONFIG_ZRAM_TRACK_ENTRY_ACTIME) o utilizza il proprio indicatore di inattività software per monitorare per quanto tempo le pagine sono rimaste invariate.Fase 3: post-elaborazione 1 - ricompressione (recupero in memoria): Le pagine che raggiungono l'età di inattività della ricompressione (da
min_idle_secondsamax_idle_seconds) vengono ricompresse.mmdscrive a/sys/block/zram0/recompressper indicare al kernel di decomprimere la paginalz4e ricomprimerla utilizzandozstd. In questo modo viene recuperata la RAM fisica senza usura della scrittura flash.Fase 4: post-elaborazione 2 - writeback (rimozione nell'archivio flash): se la pressione della memoria continua e le pagine raggiungono l'età di inattività di writeback (in genere 20 ore o più),
mmdattiva il writeback.mmdscrive su/sys/block/zram0/idlee/sys/block/zram0/writebackper espellere la pagina compressa interamente dalla RAM all'archivio flash di backup.
Configurazione dell'installazione di ZRAM
mmd carica ed elabora le seguenti proprietà di configurazione di ZRAM:
| Proprietà | Usa | Predefinito |
|---|---|---|
mmd.zram.enabled |
Indica se è attiva la configurazione mmd ZRAM. |
false |
mmd.zram.num_devices |
Il numero di dispositivi ZRAM da configurare. Per un numero N,
i dispositivi da zram0 a zram<N-1> devono essere
presenti prima che il sistema imposti sys.boot_completed=1.
Le proprietà dell'elenco dei dispositivi per ZRAM possono essere configurate in base al dispositivo.
|
1 |
mmd.zram.device_priority |
Valori di priorità da trasmettere quando chiami swapon. |
Non impostato |
mmd.zram.comp_algorithm |
Algoritmo di compressione ZRAM. Se non specificato, viene utilizzato l'algoritmo di compressione predefinito del kernel. | Non impostato |
mmd.zram.size |
Dimensioni del dispositivo ZRAM in byte o percentuale delle dimensioni della RAM del dispositivo, ad esempio
75%.
|
50% |
mmd.zram.writeback.enabled |
Se abilitare la riscrittura ZRAM. | false |
mmd.zram.writeback.device_size |
Le dimensioni del dispositivo di writeback in byte o la percentuale della partizione di dati. Le dimensioni effettive del dispositivo possono essere regolate in base allo spazio disponibile nella partizione dei dati. | 1073741824 (1 GiB) |
mmd.zram.writeback.min_free_space_mib |
Spazio libero minimo in MiB che deve essere disponibile dopo la configurazione del dispositivo di riscrittura. | 1536 (1,5 GiB) |
mmd.zram.writeback.use_nr_tags_prop |
Quando true, utilizza il valore in
mmd.zram.writeback.nr_tags per configurare la profondità della coda di
scrittura di ZRAM del dispositivo di loop. Questa è una soluzione alternativa per
le situazioni in cui non è possibile configurare il criterio SELinux del fornitore per consentire
a mmd di leggere direttamente nr_tags del dispositivo
di blocco di backup /data.
|
false |
mmd.zram.writeback.nr_tags |
Leggi i mmd.zram.writeback.use_nr_tags_prop. |
Non impostato |
mmd.zram.recompression.enabled |
Se abilitare la funzionalità di ricompressione ZRAM. | false |
mmd.zram.recompression.algorithm |
Algoritmo di ricompressione ZRAM secondario. | zstd |
Proprietà del dispositivo per ZRAM
Quando mmd.zram.num_devices è maggiore di uno, è possibile configurare facoltativamente proprietà specifiche in base al dispositivo ZRAM impostando la proprietà su un valore separato da virgole contenente esattamente mmd.zram.num_devices elementi.
Queste proprietà includono:
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
Ritiro della configurazione ZRAM esistente
Sebbene swapon_all sia ancora disponibile in Android per configurare ZRAM e lo spazio di swap basato su disco, mmd è l'approccio preferito per la gestione di ZRAM per una configurazione più semplice e funzionalità avanzate come la ricompressione ZRAM.
Quando la configurazione di mmd ZRAM è abilitata da mmd.zram.enabled:
- La configurazione di ZRAM nell'implementazione
swapon_alldiventa un'operazione nulla. - Le configurazioni ZRAM esistenti, come
config_zramWritebacknell'overlayconfig.xmle le proprietà di sistema di writebackro.zram.*, vengono ignorate.
Parametri regolabili di manutenzione ZRAM
La manutenzione di ZRAM dovrebbe funzionare immediatamente e puoi perfezionarla ulteriormente utilizzando le proprietà di sistema in questa sezione.
Pianificazione della manutenzione di ZRAM
Queste proprietà controllano come e quando le attività di manutenzione di ZRAM vengono pianificate da
system_server.
| Proprietà | Usa | Predefinito |
|---|---|---|
mm.zram.maintenance.first_delay_seconds |
Il ritardo prima dell'avvio della prima manutenzione di ZRAM. | 3600 (1 ora) |
mm.zram.maintenance.periodic_delay_seconds |
Il ritardo tra la pianificazione della manutenzione ZRAM successiva. | 3600 (1 ora) |
mm.zram.maintenance.require_device_idle |
Se avviare la manutenzione di ZRAM solo quando il dispositivo è inattivo. | true |
mm.zram.maintenance.require_battery_not_low |
Se richiedere che la batteria non sia scarica prima di avviare la manutenzione di ZRAM. | true |
Policy di writeback di ZRAM
I seguenti parametri controllano quando e quale tipo di memoria viene scritto sul dispositivo di archiviazione:
| Proprietà | Usa | Predefinito |
|---|---|---|
mmd.zram.writeback.backoff_seconds |
Tempo di backoff dall'ultima operazione di writeback. | 600 (10 minuti) |
mmd.zram.writeback.min_idle_seconds |
Combinato con mmd.zram.writeback.max_idle_seconds per calcolare
l'età di inattività di una pagina per poter essere idonea al writeback in base alla frazione di utilizzo della memoria. L'età di inattività calcolata viene interpolata in modo esponenziale
tra i due parametri per ridurre al minimo il lavoro quando non è presente una pressione sulla memoria.
|
72000 (20 ore) |
mmd.zram.writeback.max_idle_seconds |
Numero massimo di secondi utilizzati per calcolare dinamicamente l'età della pagina inattiva in base all'utilizzo della memoria. | 90000 (25 ore) |
mmd.zram.writeback.huge.enabled |
Se abilitare il writeback della pagina HUGE. |
false |
mmd.zram.writeback.idle.enabled |
Se abilitare il writeback della pagina IDLE. |
true |
mmd.zram.writeback.huge_idle.enabled |
Se abilitare il writeback della pagina HUGE_IDLE. |
true |
mmd.zram.writeback.min_bytes |
Numero minimo di byte da riscrivere in un ciclo di riscrittura inattiva. | 5242880 (5 MiB) |
mmd.zram.writeback.max_bytes |
Il numero massimo di byte da riscrivere in un ciclo di riscrittura inattiva. | 314572800 (300 MiB) |
mmd.zram.writeback.max_bytes_per_day |
Il numero massimo di byte da riscrivere in un periodo di 24 ore. | 25769803776 (24 GiB) |
mmd.zram.writeback.limit.enabled |
Indica se attivare la contabilizzazione del limite di budget di writeback giornaliero. | true |
Policy di ricompressione ZRAM
I seguenti parametri controllano quando e quale tipo di memoria viene ricompresso:
| Proprietà | Usa | Predefinito |
|---|---|---|
mmd.zram.recompression.backoff_seconds |
Tempo di backoff dall'ultima ricompressione. | 1800 (30 minuti) |
mmd.zram.recompression.min_idle_seconds |
Insieme a mmd.zram.recompression.max_idle_seconds per
calcolare l'età di inattività di una pagina per poterla ricomprimere in base
alla frazione di utilizzo della memoria. L'età di inattività calcolata viene interpolata
in modo esponenziale tra i due parametri per ridurre al minimo il lavoro quando non è presente
pressione sulla memoria.
|
7200 (2 ore) |
mmd.zram.recompression.max_idle_seconds |
Il numero massimo di secondi utilizzato per calcolare dinamicamente l'età della pagina inattiva. | 14400 (4 ore) |
mmd.zram.recompression.threshold_bytes |
Dimensioni minime in byte delle pagine ZRAM considerate per la ricompressione. | 1024 (1 KiB) |
mmd.zram.recompression.huge.enabled |
Se abilitare la ricompressione della pagina HUGE. |
true |
mmd.zram.recompression.idle.enabled |
Se abilitare la ricompressione della pagina IDLE. |
true |
mmd.zram.recompression.huge_idle.enabled |
Se abilitare la ricompressione della pagina HUGE_IDLE. |
true |
Monitoraggio delle pagine inattive ZRAM
mmd La manutenzione di ZRAM contrassegna le pagine ZRAM come inattive in base al tempo trascorso
dall'ultimo accesso. Questa funzionalità richiede l'abilitazione delle configurazioni del kernel
CONFIG_ZRAM_TRACK_ENTRY_ACTIME o CONFIG_ZRAM_MEMORY_TRACKING. CONFIG_ZRAM_TRACK_ENTRY_ACTIME è abilitato per
impostazione predefinita sui kernel GKI 6.18 e versioni successive. Nei kernel precedenti,
ha un overhead di memoria e non è abilitato per impostazione predefinita.
Se la configurazione del kernel non è attivata, la manutenzione di mmd ZRAM ricorre a una logica di sostituzione software per monitorare le pagine ZRAM inattive:
Contrassegna tutte le pagine ZRAM come inattive all'avvio di
mmd.Salta le successive manutenzioni di ZRAM finché non è trascorso il periodo di backoff richiesto.
ZRAM writeback o ricompressione delle pagine inattive. Se rimangono pagine inattive a causa dei limiti di writeback,
mmdcontinua a scrivere le pagine durante la manutenzione successiva senza contrassegnare le nuove pagine come inattive (saltando il passaggio 4).Se tutte le pagine inattive vengono riscritte, contrassegna di nuovo tutte le pagine ZRAM come inattive e torna al passaggio 2. Se il writeback di ZRAM è disattivato,
mmdcontrassegna tutte le pagine ZRAM come inattive quando la ricompressione ZRAM avviene dopo la durata di inattività della ricompressione.
Guida alla risoluzione dei problemi e alla convalida
Segui i passaggi di convalida e le procedure di risoluzione dei problemi riportati di seguito per verificare e
diagnosticare le operazioni mmd e ZRAM.
Convalida la configurazione di ZRAM
Per verificare che mmd abbia configurato correttamente ZRAM durante l'avvio:
Controlla l'algoritmo di compressione attivo e le dimensioni del disco:
cat /sys/block/zram0/comp_algorithm cat /sys/block/zram0/disksizeVerifica le proprietà di sistema
mmde lo stato del servizio in esecuzione:getprop | grep mmd.zram dumpsys -l | grep mmd
Convalida la manutenzione e il writeback di ZRAM
Verifica che le attività di manutenzione di writeback e ricompressione di ZRAM funzionino:
Controlla lo stato del dispositivo di blocco di supporto:
cat /sys/block/zram0/bd_statVerifica l'efficienza della ricompressione monitorando
/sys/block/zram0/mm_stat. Le modifiche alle dimensioni dei dati compressi dovrebbero essere visualizzate dopo i cicli di manutenzione.
Convalida il writeback per processo
Per convalidare il funzionamento del writeback per processo, puoi utilizzare quanto segue:
- Controlla
adb logcat -s mmdper i log di writeback riusciti o la diagnostica degli errori.
Problemi comuni e diagnostica
Di seguito sono riportate situazioni di errore comuni in cui l'utente potrebbe imbattersi:
WritebackDailyLimitExceeded: questo errore indica che è stata raggiunta la quota dimmd.zram.writeback.max_bytes_per_day. Quando ciò si verifica,mmdmette in pausa la riscrittura inattiva finché non avanza la finestra mobile di 24 ore.Process prefetch or writeback failed: questo errore può essere osservato in logcat quando un ioctl non va a buon fine. Tra le cause più comuni:EBADFoESRCH: il processo di destinazione è terminato prima chemmdpotesse inviarepidfdal kernel.ENOSPC: la partizione di archiviazione di backup è piena o la coda del dispositivo di loop è esaurita.
- ZRAM non configurato: se
mmdnon riesce a configurare ZRAM all'avvio, il problema potrebbe essere dovuto al fatto che gli script di inizializzazioneswapon_allo del fornitore legacy hanno bloccato/dev/block/zram0prima chemmdpotesse essere eseguito.