Android 17 以上版本支援記憶體管理 Daemon (mmd),這是一種系統 Daemon,可處理 Daemon 設定、可調整項目,以及持續進行的交換或 ZRAM 維護工作。
背景
在 mmd 推出前,Android 的 ZRAM 設定相當分散,且自訂程度有限。mmd 集中管理 ZRAM,啟用更精密的設定邏輯,並簡化新功能和架構改良項目的新增作業,解決上述問題。mmd,也能明確區分以 Java 為基礎的system_server程序,以及核心層級的交換或記憶體管理。
架構和 ZRAM 管理
開機完成後 (即 sys.boot_completed=1),mmd_setup 會嘗試使用指定參數設定 ZRAM。ZRAM 設定完成後,系統會啟用 mmd 服務,處理持續進行的維護工作。
透過 mmd 專案,維護作業會從 system_server 啟動,方法是使用 IMmd 介面將繫結器要求傳送至 mmd。mmd 會根據本身的內部政策引擎,執行 ZRAM 寫回、重新壓縮和每個程序的寫回等維護工作。您可以使用系統屬性,設定 ActivityManagerService 的排程和 ZRAM 維護政策。
系統伺服器整合 (system_server)
Java 架構的 system_server 程序會決定何時叫用 mmd。這項程序會將全域維護掃描作業與針對個別應用程式的記憶體最佳化作業分開。
正常的後續處理維護
ActivityManagerService 會使用 com.android.server.memory.ZramMaintenance 執行全域 ZRAM 維護作業。

圖 1. ZRAM 維護作業排程流程。
- 排程引擎:
ZramMaintenance使用 Android 的JobScheduler註冊週期性背景工作。 - 工作限制:為避免前景 UI 發生延遲或 CPU 爭用情形,工作會明確設定
setRequiresDeviceIdle(true)和setRequiresBatteryNotLow(true)。 - 繫結器觸發:排程器觸發
onStartJob()時,system_server會叫用mmd.doZramMaintenanceAsync()。這是單向非同步的 Binder 呼叫;system_server不會封鎖,等待維護掃描完成。mmd會將此作業排入背景工作執行緒,依序執行重新壓縮和寫回作業。
每個程序的回寫
ActivityManagerService 會使用 com.android.server.am.CachedAppOptimizer 管理每個程序的記憶體清除作業。

圖 2. 每個程序的 mmd 回寫流程。
當程序轉換為背景快取狀態時,ActivityManager 會執行記憶體壓縮。如果使用者會看到程序因記憶體不足而終止,也就是程序會代管 Activity,且 ZRAM 每個程序的寫回作業會將程序的記憶體用量降至接近零,系統就會採取下列步驟:
- 壓縮完成後,
CachedAppOptimizer會將延遲訊息 (ZRAM_WRITEBACK_MSG) 傳送至內部壓縮處理常式 (延遲時間為mZramWritebackWaitSeconds)。 - 延遲時間到期後,ActivityManager 會開啟安全程序檔案描述元
pidfd。 - 系統伺服器會呼叫
mmd.asyncWritebackProcessZramMemory(pfd, callback)。 mmd會執行每個程序的寫回 ioctl,並使用IMmdProcessWritebackCallback回報。如果成功,ActivityManager 會標記程序記錄 (setIsZramWrittenBack(app, true)),以提升程序的oom_score_adj,並將指標記錄到FrameworkStatsLog.ZRAM_WRITEBACK_EVENT。
每個程序的預先擷取
當使用者重新啟動先前已快取的應用程式 (因 UNFREEZE_REASON_ACTIVITY 而解除凍結) 時,ActivityManager 會將主要頁面錯誤從備份儲存空間造成的應用程式啟動延遲降至最低:
CachedAppOptimizer會攔截取消凍結事件,並叫用prefetchZram(app)。- 系統伺服器會使用
mmd.asyncPrefetchProcessZramMemory(pfd),透過 Binder 傳送應用程式的pidfd。mmd會發出ZRAM_ANDROID_IOC_PROCESS_PREFETCHioctl,指示核心在應用程式的主要 UI 執行緒初始化時,非同步預先擷取換出的頁面並放回 RAM。
維護和後續處理工作總覽
本節說明 mmd 執行的背景維護作業和後續處理工作,以最佳化交換空間和系統記憶體。
mmd 中的維護
在 mmd 中,「維護」是指排定的背景維護掃描,可最佳化交換空間和實體記憶體使用率,且不會影響使用中使用者前景效能。系統不會執行連續的同步掃描 (這會導致 CPU 大量喚醒和 UI 延遲),而是以非同步方式執行維護作業:
system_server會定期在 Binder 中觸發doZramMaintenanceAsync()。mmd會將要求放在背景工作佇列LowPrioWorkItem::ZramMaintenance中。mmd中有一個工作執行緒,可同時管理高優先順序佇列和低優先順序佇列。系統會優先處理高優先順序工作項目 (例如每個程序的預先擷取),並可先佔低優先順序工作項目。維護和每個程序的寫回作業會以低優先順序工作項目執行。彈出時,背景工作執行緒會依序執行兩項主要維護作業:ZRAM 重新壓縮:掃描現有的交換頁面,並使用較高比率的次要壓縮演算法 (例如
zstd) 重新壓縮閒置頁面。ZRAM 寫回:掃描閒置頁面,並將這些頁面從 RAM 完全逐出,然後透過
/data上的檔案,將這些頁面寫回備份快閃儲存空間的迴路裝置。
ZRAM 中的後續處理工作
在 Linux 核心 ZRAM 模組和 mmd 架構中,後續處理工作是指套用至記憶體頁面的非同步轉換,前提是這些頁面已由核心的標準回收路徑 (kswapd 或壓縮) 換出。
系統最初交換出網頁時,會優先考量速度:使用快速的主要壓縮演算法 (例如 lz4),並將壓縮的網頁儲存在 RAM 中。不過,隨著時間推移,許多交換的頁面會變成冷頁面或閒置頁面,例如數小時未恢復的背景快取應用程式。將冷頁面留在快速、輕度壓縮的 ZRAM 中效率不彰。
後續處理管道
mmd 實作多級式後續處理生命週期,以最佳化這些頁面:

圖 3. mmd 網頁生命週期。
階段 1:初始換出 (快速壓縮):系統會先透過 kswapd 或應用程式壓縮回收記憶體。通常第一次回收作業會使用
lz4等快速壓縮演算法,並將內容儲存在 RAM 中。階段 2:閒置標記 (老化和追蹤):
mmd閒置追蹤存取權 核心記憶體追蹤 (CONFIG_ZRAM_TRACK_ENTRY_ACTIME) 或使用軟體閒置標記,追蹤網頁閒置時間。階段 3:後續處理 1 - 重新壓縮 (記憶體回收): 達到重新壓縮閒置時間 (
min_idle_seconds至max_idle_seconds) 的網頁會重新壓縮。mmd會寫入/sys/block/zram0/recompress,指示核心解壓縮lz4頁面,然後使用zstd重新壓縮。這項作業會回收實體 RAM, 不會造成快閃寫入耗損。階段 4:後續處理 2 - 寫回 (清除至快閃儲存空間):如果記憶體壓力持續存在,且網頁達到寫回閒置時間 (通常為 20 小時以上),
mmd會觸發寫回作業。mmd會寫入/sys/block/zram0/idle和/sys/block/zram0/writeback,將壓縮頁面從 RAM 完全逐出至備份快閃儲存空間。
ZRAM 設定配置
mmd 會載入及處理下列 ZRAM 設定屬性:
| 屬性 | 使用 | 預設 |
|---|---|---|
mmd.zram.enabled |
是否啟用 mmd ZRAM 設定。 |
false |
mmd.zram.num_devices |
要設定的 ZRAM 裝置數量。如要使用數字 N,系統必須先偵測到裝置 zram0 到 zram<N-1>,才能設定 sys.boot_completed=1。您可以為每個裝置設定 ZRAM 裝置清單中的屬性。 |
1 |
mmd.zram.device_priority |
呼叫 swapon 時要傳遞的優先順序值。 |
未設定 |
mmd.zram.comp_algorithm |
ZRAM 壓縮演算法。如未指定,系統會使用核心預設壓縮演算法。 | 未設定 |
mmd.zram.size |
以位元組為單位的 ZRAM 裝置大小,或裝置 RAM 大小的百分比,例如:
75%。
|
50% |
mmd.zram.writeback.enabled |
是否啟用 ZRAM 寫回功能。 | false |
mmd.zram.writeback.device_size |
回寫裝置的大小 (以位元組為單位),或資料分割區的百分比。實際裝置大小可根據資料分割區的可用空間調整。 | 1073741824 (1 GiB) |
mmd.zram.writeback.min_free_space_mib |
寫回裝置設定後,必須提供的最小可用空間 (以 MiB 為單位)。 | 1536 (1.5 GiB) |
mmd.zram.writeback.use_nr_tags_prop |
當 true 使用 mmd.zram.writeback.nr_tags 中的值時,會設定迴路裝置的佇列深度,以支援 ZRAM 寫回。如果無法設定供應商 SELinux 政策,允許 mmd 直接讀取區塊裝置備份 nr_tags 的 nr_tags,可以採用這個解決方法。/data |
false |
mmd.zram.writeback.nr_tags |
詳情請參閱《mmd.zram.writeback.use_nr_tags_prop》。 |
未設定 |
mmd.zram.recompression.enabled |
是否啟用 ZRAM 重新壓縮功能。 | false |
mmd.zram.recompression.algorithm |
次要 ZRAM 重新壓縮演算法。 | zstd |
每個 ZRAM 裝置的屬性
如果 mmd.zram.num_devices 大於 1,您可以將屬性設為以半形逗號分隔的值 (內含的元素數量必須正好是 mmd.zram.num_devices 個),選擇性地為每個 ZRAM 裝置設定特定屬性。這些屬性包括:
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
現有 ZRAM 設定即將淘汰
雖然 Android 仍提供 swapon_all,可設定 ZRAM 和以磁碟為基礎的交換空間,但 mmd 是 ZRAM 管理的偏好方法,可簡化設定並提供 ZRAM 重新壓縮等進階功能。
mmd啟用 mmd.zram.enabled ZRAM 設定後:
swapon_all實作中的 ZRAM 設定會變成無運算。- 系統會忽略現有的 ZRAM 設定,例如疊加層
config_zramWriteback檔案中的config.xml和ro.zram.*回寫系統屬性。
ZRAM 維護可調整項目
ZRAM 維護作業應該可以立即運作,您可以使用本節中的系統屬性進一步微調。
ZRAM 維護排程
這些屬性會控管 system_server 排定 ZRAM 維護工作的時間和方式。
| 屬性 | 使用 | 預設 |
|---|---|---|
mm.zram.maintenance.first_delay_seconds |
啟動第一次 ZRAM 維護作業前的延遲時間。 | 3600 (1 小時) |
mm.zram.maintenance.periodic_delay_seconds |
後續 ZRAM 維護排程之間的延遲時間。 | 3600 (1 小時) |
mm.zram.maintenance.require_device_idle |
是否只在裝置閒置時啟動 ZRAM 維護作業。 | true |
mm.zram.maintenance.require_battery_not_low |
是否要在啟動 ZRAM 維護作業前,要求電池電量充足。 | true |
ZRAM 回寫政策
下列參數可控制寫入備份裝置的記憶體類型和時間:
| 屬性 | 使用 | 預設 |
|---|---|---|
mmd.zram.writeback.backoff_seconds |
上次回寫作業後經過的延遲時間。 | 600 (10 分鐘) |
mmd.zram.writeback.min_idle_seconds |
與 mmd.zram.writeback.max_idle_seconds 搭配使用,根據記憶體使用率分數計算頁面的閒置時間,判斷是否符合回寫資格。系統會在這兩個參數之間以指數方式插補計算出的閒置時間,盡量減少工作量,同時避免記憶體壓力。 |
72000 (20 小時) |
mmd.zram.writeback.max_idle_seconds |
系統會根據記憶體用量動態計算閒置網頁的存留時間,這個屬性就是計算時使用的秒數上限。 | 90000 (25 小時) |
mmd.zram.writeback.huge.enabled |
是否啟用 HUGE 頁面回寫。 |
false |
mmd.zram.writeback.idle.enabled |
是否啟用 IDLE 頁面回寫。 |
true |
mmd.zram.writeback.huge_idle.enabled |
是否啟用 HUGE_IDLE 頁面回寫。 |
true |
mmd.zram.writeback.min_bytes |
一次閒置寫回作業的最低寫回位元組數。 | 5242880 (5 MiB) |
mmd.zram.writeback.max_bytes |
一次閒置寫回作業中寫回的位元組數上限。 | 314572800 (300 MiB) |
mmd.zram.writeback.max_bytes_per_day |
24 小時內寫回的位元組數上限。 | 25769803776 (24 GiB) |
mmd.zram.writeback.limit.enabled |
是否啟用每日回寫預算上限會計。 | true |
ZRAM 重新壓縮政策
下列參數可控制記憶體重新壓縮的時間和類型:
| 屬性 | 使用 | 預設 |
|---|---|---|
mmd.zram.recompression.backoff_seconds |
上次重新壓縮後的回溯時間。 | 1800 (30 分鐘) |
mmd.zram.recompression.min_idle_seconds |
與 mmd.zram.recompression.max_idle_seconds 搭配使用,計算網頁的閒置時間,判斷網頁是否符合根據記憶體使用率分數重新壓縮的資格。系統會在這兩個參數之間以指數方式插補計算出的閒置時間,盡量減少工作量,同時避免記憶體壓力過大。 |
7200 (2 小時) |
mmd.zram.recompression.max_idle_seconds |
計算閒置網頁時間上限 (以秒為單位)。 | 14400 (4 小時) |
mmd.zram.recompression.threshold_bytes |
系統會考慮重新壓縮的 ZRAM 頁面大小下限 (以位元組為單位)。 | 1024 (1 KiB) |
mmd.zram.recompression.huge.enabled |
是否啟用HUGE頁面重新壓縮。 |
true |
mmd.zram.recompression.idle.enabled |
是否啟用IDLE頁面重新壓縮。 |
true |
mmd.zram.recompression.huge_idle.enabled |
是否啟用HUGE_IDLE頁面重新壓縮。 |
true |
ZRAM 閒置頁面追蹤
mmd ZRAM 維護作業會根據 ZRAM 頁面上次存取時間,將這些頁面標示為閒置。這項功能需要啟用 CONFIG_ZRAM_TRACK_ENTRY_ACTIME 或 CONFIG_ZRAM_MEMORY_TRACKING 核心設定。在 GKI 核心 6.18 以上版本中,CONFIG_ZRAM_TRACK_ENTRY_ACTIME 預設為啟用。在較舊的 Kernel 中,這項功能會造成記憶體負擔,因此預設為停用。
如果未啟用核心設定,mmd ZRAM 維護作業會改用軟體替代邏輯,追蹤閒置的 ZRAM 頁面:
在
mmd啟動時,將所有 ZRAM 頁面標示為閒置。略過下一次 ZRAM 維護作業,直到必要的回退期結束為止。
ZRAM 寫回或重新壓縮閒置頁面。如果因回寫限制而有閒置頁面,
mmd會在下一次維護時繼續回寫頁面,不會將新頁面標示為閒置 (略過步驟 4)。如果所有閒置頁面都已寫回,請再次將所有 ZRAM 頁面標示為閒置,然後返回步驟 2。如果停用 ZRAM 寫回功能,
mmd會在重新壓縮閒置時間過後,重新壓縮 ZRAM 時,將所有 ZRAM 頁面標示為閒置。
疑難排解與驗證指南
請按照下列驗證步驟和疑難排解程序,驗證及診斷 mmd 和 ZRAM 作業。
驗證 ZRAM 設定
如要確認 mmd 在開機期間是否已成功設定 ZRAM,請執行下列步驟:
檢查有效的壓縮演算法和磁碟大小:
cat /sys/block/zram0/comp_algorithm cat /sys/block/zram0/disksize驗證
mmd系統屬性和執行中的服務狀態:getprop | grep mmd.zram dumpsys -l | grep mmd
驗證 ZRAM 維護和回寫
確認 ZRAM 寫回和重新壓縮維護工作是否正常運作:
檢查支援的區塊裝置狀態:
cat /sys/block/zram0/bd_stat監控
/sys/block/zram0/mm_stat,瞭解重新壓縮效率。 維護週期結束後,壓縮資料大小的變化就會顯示出來。
驗證每個程序的回寫
您可以使用下列項目,驗證每個程序的回寫功能是否正常運作:
- 檢查
adb logcat -s mmd,確認是否成功寫回記錄或失敗診斷。
常見問題和診斷
使用者可能會遇到下列常見錯誤情況:
WritebackDailyLimitExceeded:這個錯誤表示已達mmd.zram.writeback.max_bytes_per_day配額上限。發生這種情況時,mmd會暫停閒置寫回作業,直到 24 小時的滾動時間範圍前進為止。Process prefetch or writeback failed:ioctl 失敗時,可以在 logcat 中觀察到這項錯誤。常見原因包括:EBADF或ESRCH:目標程序在mmd將pidfd分派至核心之前結束。ENOSPC:備份儲存空間分割區已滿,或迴路裝置佇列已用盡。
- ZRAM 未設定:如果
mmd無法在開機時設定 ZRAM,可能是因為舊版swapon_all或供應商的 init 指令碼在mmd執行前鎖定/dev/block/zram0。