Der Daemon-Prozess des Android Low Memory Killer (lmkd
) überwacht den Arbeitsspeicherstatus eines laufenden Android-Systems und reagiert auf hohen Arbeitsspeicherdruck, indem er die am wenigsten wichtigen Prozesse beendet, um die Systemleistung auf einem akzeptablen Niveau zu halten.
Arbeitsspeicherdruck
Wenn auf einem Android-System mehrere Prozesse parallel ausgeführt werden, kann es vorkommen, dass der Systemspeicher erschöpft ist und Prozesse, die mehr Arbeitsspeicher benötigen, spürbare Verzögerungen aufweisen. Speicherdruck ist ein Zustand, in dem das System nicht mehr genügend Arbeitsspeicher hat. Android muss dann Arbeitsspeicher freigeben, um den Druck zu verringern. Dazu werden unwichtige Prozesse gedrosselt oder beendet und Prozesse aufgefordert, nicht kritische, im Cache gespeicherte Ressourcen freizugeben.
Bisher hat Android den Systemarbeitsspeicherbedarf mit einem LMK-Treiber (Low-Memory-Killer) im Kernel überwacht. Dieser starre Mechanismus basiert auf fest codierten Werten. Ab Kernel 4.12 wird der LMK-Treiber aus dem Upstream-Kernel entfernt und der lmkd
-Nutzerbereich übernimmt die Aufgaben der Arbeitsspeicherüberwachung und des Beendens von Prozessen.
Informationen zum Druckabfall
Android 10 und höher unterstützen einen neuen lmkd
-Modus, in dem PSI-Monitore (Kernel Pressure Stall Information) zur Erkennung von Arbeitsspeicherbelastung verwendet werden. Das PSI-Patchset im Upstream-Kernel (rückportiert auf die Kernelversionen 4.9 und 4.14) misst die Zeit, die Aufgaben aufgrund von Speichermangel verzögert werden. Da sich diese Verzögerungen direkt auf die Nutzerfreundlichkeit auswirken, sind sie ein praktischer Messwert, um den Schweregrad der Arbeitsspeicherauslastung zu bestimmen. Der Upstream-Kernel enthält auch PSI-Monitore, mit denen privilegierte Userspace-Prozesse (z. B. lmkd
) Grenzwerte für diese Verzögerungen festlegen und Ereignisse vom Kernel abonnieren können, wenn ein Grenzwert überschritten wird.
PSI-Monitore im Vergleich zu vmpressure-Signalen
Da die vmpressure
-Signale (die vom Kernel zur Erkennung von Speichermangel generiert und von lmkd
verwendet werden) oft zahlreiche Falschmeldungen enthalten, muss lmkd
filtern, um festzustellen, ob der Speicher wirklich überlastet ist.
Dies führt zu unnötigen lmkd
-Aktivierungen und der Verwendung zusätzlicher Rechenressourcen. Die Verwendung von PSI-Monitoren führt zu einer genaueren Erkennung des Speicherdrucks und minimiert den Filteraufwand.
PSI-Monitore verwenden
Wenn Sie PSI-Monitore anstelle von vmpressure
-Ereignissen verwenden möchten, konfigurieren Sie die Property ro.lmk.use_psi
. Der Standardwert ist true
. PSI ist also der Standardmechanismus zur Erkennung von Speicherdruck für lmkd
. Da PSI-Monitore Kernel-Unterstützung erfordern, muss der Kernel die PSI-Backport-Patches enthalten und mit aktivierter PSI-Unterstützung (CONFIG_PSI=y
) kompiliert werden.
Nachteile des In-Kernel-LMK-Treibers
Der LMK-Treiber wird unter Android aus verschiedenen Gründen eingestellt, darunter:
- Geräte mit wenig RAM mussten aggressiv optimiert werden und selbst dann war die Leistung bei Arbeitslasten mit einem großen dateibasierten aktiven Pagecache schlecht. Die schlechte Leistung führte zu einem Thrashing und keinen Kills.
- Der LMK-Kernel-Treiber basierte auf Grenzwerten für kostenlosen Arbeitsspeicher, ohne dass eine Skalierung basierend auf der Arbeitsspeicherauslastung erfolgte.
- Aufgrund der Starrheit des Designs haben Partner den Treiber oft angepasst, damit er auf ihren Geräten funktioniert.
- Der LMK-Treiber wurde in die Slab Shrinker API eingebunden, die nicht für rechenintensive Vorgänge wie das Suchen und Beenden von Zielprozessen konzipiert war. Dadurch wurde der
vmscan
-Prozess verlangsamt.
Userspace-lmkd
Der Userspace-lmkd
implementiert dieselbe Funktionalität wie der In-Kernel-Treiber, verwendet aber vorhandene Kernelmechanismen, um den Speicherdruck zu erkennen und zu schätzen. Dazu gehören die Verwendung von vom Kernel generierten vmpressure
-Ereignissen oder PSI-Monitoren (Pressure Stall Information), um Benachrichtigungen über den Arbeitsspeicherverbrauch zu erhalten, sowie die Verwendung von Arbeitsspeicher-Cgroup-Funktionen, um die jedem Prozess zugewiesenen Arbeitsspeicherressourcen basierend auf der Prozesswichtigkeit zu begrenzen.
Userspace-lmkd in Android 10 verwenden
In Android 9 und höher wird der Nutzerbereich lmkd
aktiviert, wenn kein LMK-Treiber im Kernel erkannt wird. Da für den Userspace-lmkd
die Unterstützung von Memory-Cgroups durch den Kernel erforderlich ist, muss der Kernel mit den folgenden Konfigurationseinstellungen kompiliert werden:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
Strategien zum Beenden von Prozessen
Der Userspace lmkd
unterstützt Kill-Strategien, die auf vmpressure
-Ereignissen oder PSI-Monitoren, deren Schweregrad und anderen Hinweisen wie der Swap-Auslastung basieren. Die Strategien zum Beenden von Apps unterscheiden sich zwischen Geräten mit wenig Arbeitsspeicher und leistungsstarken Geräten:
- Auf Geräten mit wenig Arbeitsspeicher sollte das System eine höhere Speicherauslastung als normalen Betriebsmodus tolerieren.
- Auf leistungsstarken Geräten sollte eine hohe Speicherauslastung als abnormal angesehen und behoben werden, bevor sie sich auf die Gesamtleistung auswirkt.
Sie können die Beendigungsstrategie mit der Property ro.config.low_ram
konfigurieren.
Der Userspace-LMK lmkd
unterstützt auch einen Legacy-Modus, in dem er mithilfe derselben Strategien wie der In-Kernel-LMK-Treiber (d. h. Grenzwerte für kostenlosen Arbeitsspeicher und Dateicache) Entscheidungen zum Beenden von Prozessen trifft. Wenn Sie den Legacy-Modus aktivieren möchten, legen Sie die Eigenschaft ro.lmk.use_minfree_levels
auf true
fest.
lmkd konfigurieren
Konfigurieren Sie lmkd
für ein bestimmtes Gerät mit den folgenden Attributen.
Attribut | Verwenden | Standard |
---|---|---|
ro.config.low_ram
|
Geben Sie an, ob es sich bei dem Gerät um ein Gerät mit wenig RAM oder ein leistungsstarkes Gerät handelt. | false
|
ro.lmk.use_psi |
Verwenden Sie PSI-Monitore anstelle von vmpressure -Ereignissen. |
true |
ro.lmk.use_minfree_levels
|
Verwenden Sie Grenzwerte für kostenlosen Arbeitsspeicher und Dateicache, um Entscheidungen zum Beenden von Prozessen zu treffen (d. h. passen Sie die Funktionalität des LMK-Treibers im Kernel an). | false
|
ro.lmk.low
|
Die Mindestpunktzahl für oom_adj für Prozesse, die bei niedrigem vmpressure -Level beendet werden können.
|
1001 (deaktiviert) |
ro.lmk.medium
|
Der Mindestwert für oom_adj für Prozesse, die auf mittlerem vmpressure -Niveau beendet werden können.
|
800 (im Cache gespeicherte oder nicht essenzielle Dienste) |
ro.lmk.critical
|
Die Mindestpunktzahl für oom_adj für Prozesse, die auf kritischem vmpressure -Niveau beendet werden können.
|
0 (beliebiger Prozess) |
ro.lmk.critical_upgrade
|
Upgrade auf kritische Stufe aktivieren | false
|
ro.lmk.upgrade_pressure
|
Der maximale mem_pressure , bei dem das Niveau angehoben wird, weil das System zu viel tauscht.
|
100 (deaktiviert) |
ro.lmk.downgrade_pressure
|
Die Mindest-mem_pressure , bei der ein vmpressure -Ereignis ignoriert wird, weil noch genügend kostenloser Arbeitsspeicher verfügbar ist.
|
100 (deaktiviert) |
ro.lmk.kill_heaviest_task
|
Die rechenintensivste infrage kommende Aufgabe beenden (beste Entscheidung) im Vergleich zu einer beliebigen infrage kommenden Aufgabe (schnelle Entscheidung). | false
|
ro.lmk.kill_timeout_ms
|
Dauer in Millisekunden nach dem Beenden, wenn kein weiteres Beenden erfolgt. | 0 (deaktiviert) |
ro.lmk.debug
|
Aktivieren Sie lmkd -Fehlerbehebungsprotokolle.
|
false
|
Beispiel für die Gerätekonfiguration:
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
lmkd im Userspace in Android 11
In Android 11 wird die lmkd
durch eine neue Beendigungsstrategie verbessert. Bei der Beendigungsstrategie wird ein PSI-Mechanismus zur Erkennung von Arbeitsspeicherbelastung verwendet, der in Android 10 eingeführt wurde. lmkd
in Android 11 berücksichtigt die Arbeitsspeicherressourcennutzung und das Thrashing, um Arbeitsspeichermangel und Leistungseinbußen zu verhindern.
Diese Strategie ersetzt frühere Strategien und kann sowohl auf leistungsstarken Geräten als auch auf Geräten mit wenig RAM (Android Go) verwendet werden.
Kernel-Anforderungen
Für Android 11-Geräte sind für lmkd
die folgenden Kernelfunktionen erforderlich:
- PSI-Patches einfügen und PSI aktivieren (Backports sind in den Android Common Kernels 4.9, 4.14 und 4.19 verfügbar).
- Fügen Sie Patches für die PIDFD-Unterstützung hinzu (Backports sind in den gemeinsamen Android-Kerneln 4.9, 4.14 und 4.19 verfügbar).
- Auf Geräten mit wenig Arbeitsspeicher sollten Sie Arbeitsspeicher-Cgroups einbeziehen.
Der Kernel muss mit den folgenden Konfigurationseinstellungen kompiliert werden:
CONFIG_PSI=y
lmkd in Android 11 konfigurieren
Die Strategie zum Beenden von Prozessen im Arbeitsspeicher in Android 11 unterstützt die unten aufgeführten Abstimmungsregler und Standardeinstellungen. Diese Funktionen sind sowohl auf leistungsstarken Geräten als auch auf Geräten mit wenig RAM verfügbar.
Attribut | Verwenden | Standard | |
---|---|---|---|
Hohe Leistung | Geringer RAM | ||
ro.lmk.psi_partial_stall_ms |
Der Schwellenwert für den teilweisen PSI-Stillstand in Millisekunden, der die Benachrichtigung über wenig Arbeitsspeicher auslöst. Wenn das Gerät Benachrichtigungen zum Speicherdruck zu spät erhält, verringern Sie diesen Wert, um frühere Benachrichtigungen auszulösen. Wenn Benachrichtigungen zum Arbeitsspeicher unnötigerweise ausgelöst werden, erhöhen Sie diesen Wert, um das Gerät weniger anfällig für Rauschen zu machen. | 70 |
200 |
ro.lmk.psi_complete_stall_ms |
Der vollständige PSI-Stall-Grenzwert in Millisekunden zum Auslösen kritischer Speicherbenachrichtigungen. Wenn das Gerät kritische Benachrichtigungen zum Arbeitsspeicher zu spät erhält, verringern Sie diesen Wert, um Benachrichtigungen früher auszulösen. Wenn Benachrichtigungen zu kritischem Arbeitsspeicherausfall unnötig ausgelöst werden, erhöhen Sie diesen Wert, um das Gerät weniger anfällig für Störungen zu machen. | 700 |
|
ro.lmk.thrashing_limit |
Die maximale Anzahl von Working-Set-Refaults als Prozentsatz der gesamten Dateibackend-Pagecache-Größe. Wenn der Wert für „Workingset refaults“ über diesem Wert liegt, wird davon ausgegangen, dass das System seinen Seitencache überlastet. Wenn die Leistung des Geräts durch die Speicherauslastung beeinträchtigt wird, verringern Sie den Wert, um das Thrashing zu begrenzen. Wenn die Leistung des Geräts unnötigerweise aufgrund von Thrashing beeinträchtigt wird, erhöhen Sie den Wert, um mehr Thrashing zuzulassen. | 100 |
30 |
ro.lmk.thrashing_limit_decay |
Der als Prozentsatz des ursprünglichen Schwellenwerts ausgedrückte Schwellenwertverfall für Thrashing, der verwendet wird, um den Schwellenwert zu senken, wenn sich das System auch nach dem Beenden nicht erholt. Wenn durch kontinuierliches Thrashing unnötige Beendigungen verursacht werden, verringern Sie den Wert. Wenn die Reaktion auf kontinuierliches Thrashing nach einem Kill zu langsam ist, erhöhen Sie den Wert. | 10 |
50 |
ro.lmk.swap_util_max |
Die maximale Menge an ausgelagertem Arbeitsspeicher als Prozentsatz des insgesamt auslagerbaren Arbeitsspeichers. Wenn der ausgelagerte Arbeitsspeicher über dieses Limit hinaus anwächst, bedeutet das, dass das System den größten Teil des auslagerbaren Arbeitsspeichers ausgelagert hat und immer noch unter Druck steht.
Das kann passieren, wenn nicht auslagerungsfähige Zuweisungen zu einem hohen Arbeitsspeicherbedarf führen, der nicht durch Auslagern behoben werden kann, da der größte Teil des auslagerungsfähigen Arbeitsspeichers bereits ausgelagert ist. Der Standardwert ist 100, wodurch diese Prüfung deaktiviert wird. Wenn die Leistung des Geräts bei hohem Speicherdruck beeinträchtigt wird, während die Swap-Auslastung hoch ist und der kostenlose Swap-Speicher nicht auf ro.lmk.swap_free_low_percentage sinkt, verringern Sie den Wert, um die Swap-Auslastung zu begrenzen. |
100 |
100 |
Die folgenden alten Abstimmungsoptionen funktionieren auch mit der neuen Beendigungsstrategie.
Attribut | Verwenden | Standard | |
---|---|---|---|
Hohe Leistung | Geringer RAM | ||
ro.lmk.swap_free_low_percentage |
Der Anteil des kostenlosen Auslagerungsspeichers am gesamten Auslagerungsspeicher in Prozent. `lmkd` verwendet diesen Wert als Grenzwert, ab dem das System als swap-speicherhungrig gilt. Wenn `lmkd` Prozesse beendet, obwohl noch viel Speicherplatz im Swap-Bereich vorhanden ist, verringern Sie den Prozentsatz. Wenn `lmkd`-Kills zu spät erfolgen und OOM-Kills zugelassen werden, erhöhen Sie den Prozentsatz. | 20 |
10 |
ro.lmk.debug |
Dadurch werden Debug-Logs für `lmkd` aktiviert. Aktiviere das Debugging während der Abstimmung. | false |