Android 低記憶體殺手守護程式 ( lmkd
) 進程監視正在運行的 Android 系統的記憶體狀態,並透過終止最不重要的進程來應對高記憶體壓力,以保持系統效能在可接受的水平。
關於記憶體壓力
並行運行多個進程的 Android 系統可能會遇到系統記憶體耗盡以及需要更多記憶體的進程出現明顯延遲的情況。記憶體壓力,系統記憶體不足的一種狀態,需要Android透過限製或殺死不重要的進程、請求進程釋放非關鍵的快取資源等方式釋放記憶體(以緩解壓力)。
從歷史上看,Android 使用核心低記憶體殺手 (LMK) 驅動程式來監控系統記憶體壓力,這是一種依賴硬編碼值的嚴格機制。從核心 4.12 開始,LMK 驅動程式已從上游核心中刪除,用戶空間lmkd
執行記憶體監視和進程終止任務。
壓力失速資訊
Android 10 及更高版本支援新的lmkd
模式,該模式使用核心壓力停頓資訊 (PSI) 監視器進行記憶體壓力偵測。上游核心(向後移植到 4.9 和 4.14 核心)中的 PSI 補丁集測量任務由於記憶體短缺而延遲的時間量。由於這些延遲直接影響使用者體驗,因此它們代表了確定記憶體壓力嚴重程度的便利指標。上游核心還包括 PSI 監視器,允許特權用戶空間進程(例如lmkd
)指定這些延遲的閾值,並在違反閾值時從核心訂閱事件。
PSI 監視器與 vmPressure 訊號
由於vmpressure
訊號(由核心產生用於記憶體壓力檢測並由lmkd
使用)通常包含大量誤報,因此lmkd
必須執行過濾以確定記憶體是否處於真正的壓力下。這會導致不必要的lmkd
喚醒並使用額外的運算資源。使用 PSI 監視器可以實現更準確的記憶體壓力檢測並最大限度地減少過濾開銷。
使用 PSI 監視器
若要使用 PSI 監視器而不是vmpressure
事件,請設定ro.lmk.use_psi
屬性。預設值為true
,使 PSI 監視成為lmkd
記憶體壓力偵測的預設機制。由於 PSI 監視器需要內核支持,因此內核必須包含 PSI 向後移植補丁,並在啟用 PSI 支援的情況下進行編譯 ( CONFIG_PSI=y
)。
內核 LMK 驅動程式的缺點
由於許多問題,Android 棄用了 LMK 驅動程序,其中包括:
- 低 RAM 設備必須進行積極調整,即使這樣,在具有大型文件支援的活動頁面快取的工作負載上也會表現不佳。糟糕的表現導致了慘烈的毆打,但沒有殺死任何人。
- LMK 核心驅動程式依賴可用記憶體限制,不會根據記憶體壓力進行擴展。
- 由於設計的剛性,合作夥伴經常自訂驅動程序,以便它可以在他們的設備上運行。
- LMK 驅動程式連接到了slabshrinkerAPI,該API並不是為繁重的操作而設計的,例如搜尋目標並殺死它們,這會減慢
vmscan
進程。
用戶空間 lmkd
使用者空間lmkd
實現與核心驅動程式相同的功能,但使用現有的核心機制來檢測和估計記憶體壓力。此類機制包括使用核心產生的vmpressure
事件或壓力停頓資訊 (PSI) 監視器來取得有關記憶體壓力等級的通知,以及使用記憶體 cgroup 功能根據進程重要性限制分配給每個進程的記憶體資源。
在 Android 10 中使用用戶空間 lmkd
在 Android 9 及更高版本中,如果未偵測到核心 LMK 驅動程序,則會啟動用戶空間lmkd
。由於用戶空間lmkd
需要核心支援記憶體 cgroup,因此必須使用以下組態設定來編譯核心:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
擊殺策略
使用者空間lmkd
支援基於vmpressure
事件或 PSI 監視器、其嚴重性以及其他提示(例如交換利用率)的終止策略。低記憶體設備和高效能設備的終止策略有所不同:
- 在低記憶體設備上,系統應容忍較高的記憶體壓力作為正常操作模式。
- 在高效能設備上,記憶體壓力應被視為異常情況並在影響整體效能之前修復。
您可以使用ro.config.low_ram
屬性來設定終止策略。有關詳細信息,請參閱低內存配置。
使用者空間lmkd
也支援傳統模式,在該模式下,它使用與核心 LMK 驅動程式相同的策略(即可用記憶體和檔案快取閾值)做出終止決策。若要啟用舊模式,請將ro.lmk.use_minfree_levels
屬性設為true
。
配置lmkd
使用以下屬性為特定設備配置lmkd
。
財產 | 使用 | 預設 |
---|---|---|
ro.config.low_ram | 指定設備是低 RAM 還是高效能設備。 | false |
ro.lmk.use_psi | 使用 PSI 監視器(而非vmpressure 事件)。 | true |
ro.lmk.use_minfree_levels | 使用可用記憶體和檔案快取閾值來做出進程終止決策(即,與核心 LMK 驅動程式的功能相符)。 | false |
ro.lmk.low | 在低vmpressure 等級下有資格被終止的程序的最低oom_adj 分數。 | 1001 (已停用) |
ro.lmk.medium | 有資格在中等vmpressure 級別終止的進程的最低oom_adj 分數。 | 800 (快取或非必要服務) |
ro.lmk.critical | 有資格在臨界vmpressure 層級終止的進程的最低oom_adj 分數。 | 0 (任何過程) |
ro.lmk.critical_upgrade | 啟用升級到關鍵等級。 | false |
ro.lmk.upgrade_pressure | 由於系統交換過多而升級等級的最大mem_pressure 。 | 100 (已停用) |
ro.lmk.downgrade_pressure | 由於仍有足夠的可用記憶體而忽略vmpressure 事件的最小mem_pressure 。 | 100 (已停用) |
ro.lmk.kill_heaviest_task | 殺死最重的合格任務(最佳決策)與任何合格任務(快速決策)。 | true |
ro.lmk.kill_timeout_ms | 殺戮後不會進行額外殺戮的持續時間(以毫秒為單位)。 | 0 (已停用) |
ro.lmk.debug | 啟用lmkd 調試日誌。 | false |
設備配置範例:
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
Android 11 中的使用者空間 lmkd
Android 11 透過引進新的查殺策略改進了lmkd
。查殺策略使用 Android 10 中引入的 PSI 機制進行記憶體lmkd
偵測。這種查殺策略取代了先前的策略,並且可以在高效能和低 RAM (Android Go) 裝置上使用。
內核要求
對於 Android 11 設備, lmkd
需要以下核心功能:
- 包含 PSI 修補程式並啟用 PSI(Android 通用核心 4.9、4.14 和 4.19 中提供向後移植)。
- 包括 PIDFD 支援補丁(Android 通用核心 4.9、4.14 和 4.19 中提供向後移植)。
- 對於低 RAM 設備,包括記憶體 cgroup。
必須使用以下配置設定來編譯核心:
CONFIG_PSI=y
在 Android 11 中設定 lmkd
Android 11 中的記憶體終止策略支援下面列出的調整旋鈕和預設值。這些功能適用於高效能和低 RAM 設備。
財產 | 使用 | 預設 | |
---|---|---|---|
高效能 | 低記憶體 | ||
ro.lmk.psi_partial_stall_ms | 用於觸發記憶體不足通知的部分 PSI 停頓閾值(以毫秒為單位)。如果裝置太晚收到記憶體壓力通知,請減少此值以觸發更早的通知。如果不必要地觸發記憶體壓力通知,請增加此值以使裝置對雜訊不那麼敏感。 | 70 | 200 |
ro.lmk.psi_complete_stall_ms | 用於觸發關鍵記憶體通知的完整 PSI 停頓閾值(以毫秒為單位)。如果裝置太晚收到嚴重記憶體壓力通知,請減少此值以觸發更早的通知。如果不必要地觸發關鍵記憶體壓力通知,請增加此值以使裝置對雜訊不那麼敏感。 | 700 | |
ro.lmk.thrashing_limit | 工作集的最大數量會傳回為檔案支援的頁面快取總大小的百分比。工作集重新高於此值意味著系統被認為正在破壞其頁面快取。如果裝置的效能在記憶體壓力期間受到影響,請減少該值以限制抖動。如果由於抖動原因而不必要地降低了設備的效能,請增加該值以允許更多的抖動。 | 100 | 30 |
ro.lmk.thrashing_limit_decay | 抖動閾值衰減表示為原始閾值的百分比,用於在系統無法恢復(即使在終止後)時降低閾值。如果連續的毆打產生不必要的殺戮,請減少該值。如果擊殺後連續猛擊的反應太慢,請增加該數值。 | 10 | 50 |
ro.lmk.swap_util_max | 最大交換記憶體量佔總可交換記憶體的百分比。當交換內存增長超過此限制時,表示系統交換了大部分可交換內存,並且仍然處於壓力之下。當不可交換分配產生記憶體壓力且無法透過交換緩解時,就會發生這種情況,因為大多數可交換記憶體已被換出。預設值為 100,這會有效停用此檢查。如果裝置的效能在記憶體壓力期間受到影響,同時交換利用率很高且可用交換等級沒有下降到ro.lmk.swap_free_low_percentage ,請減少該值以限制交換利用率。 | 100 | 100 |
以下舊的調整旋鈕也適用於新的殺戮策略。
財產 | 使用 | 預設 | |
---|---|---|---|
高效能 | 低記憶體 | ||
ro.lmk.swap_free_low_percentage | 可用交換空間佔總交換空間的百分比。 `lmkd` 使用此值作為何時將系統視為交換空間不足的閾值。如果「lmkd」在交換空間太多時終止,請減少百分比。如果「lmkd」殺戮發生得太晚,導致 OOM 殺戮發生,請增加百分比。 | 20 | 10 |
ro.lmk.debug | 這將啟用“lmkd”調試日誌。調整時啟用調試。 | false |