Android 低內存殺手守護進程 ( lmkd
) 進程監控正在運行的 Android 系統的內存狀態,並通過殺死最不重要的進程來對高內存壓力做出反應,以使系統保持在可接受的水平。
關於內存壓力
並行運行多個進程的 Android 系統可能會遇到系統內存耗盡且需要更多內存的進程會出現明顯延遲的情況。內存壓力,系統內存不足的一種狀態,要求Android通過限製或殺死不重要的進程、請求進程釋放非關鍵緩存資源等來釋放內存(以減輕壓力)。
從歷史上看,Android 使用內核內低內存殺手 (LMK) 驅動程序監控系統內存壓力,這是一種依賴硬編碼值的剛性機制。從內核 4.12 開始,LMK 驅動程序從上游內核中移除,用戶空間lmkd
執行內存監控和進程終止任務。
壓力失速信息
Android 10 及更高版本支持新的lmkd
模式,該模式使用內核壓力停頓信息 (PSI) 監視器進行內存壓力檢測。上游內核中的 PSI 補丁集(向後移植到 4.9 和 4.14 內核)測量由於內存不足而導致任務延遲的時間量。由於這些延遲直接影響用戶體驗,因此它們代表了確定內存壓力嚴重程度的便捷指標。上游內核還包括 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 驅動程序與slab shrinker API 掛鉤,該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 機制。Android 11 中的lmkd
考慮了內存資源使用水平和抖動,以防止內存不足和性能下降。這種查殺策略取代了以前的策略,可以在高性能和低內存(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 |