Der Android Low Memory Killer-Daemon-Prozess (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 werden aufgefordert, nicht kritische zwischengespeicherte Ressourcen freizugeben.
Bisher wurde der Arbeitsspeicherbedarf von Android mit einem LMK-Treiber (Low-Memory-Killer) im Kernel überwacht. Dieser starre Mechanismus basiert auf fest codierten Werten. Ab Kernel 4.12 wurde der LMK-Treiber aus dem Upstream-Kernel entfernt und der Userspace lmkd ü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, um die Aufgaben aufgrund von Arbeitsspeichermangel 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 aus dem Kernel abonnieren können, wenn ein Grenzwert überschritten wird.
PSI-Messwerte 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. Durch die Verwendung von PSI-Monitoren wird der Speicherdruck genauer erkannt und der Filteraufwand minimiert.
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 Seitenflattern und keinen Kills.
- Der LMK-Kerneltreiber 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 Arbeitsspeicherdruck zu erhalten, und die Verwendung von Arbeitsspeicher-Cgroup-Funktionen, um die jedem Prozess zugewiesenen Arbeitsspeicherressourcen basierend auf der Prozesswichtigkeit zu begrenzen.
Userspace-lmkd in Android 10 verwenden
Unter Android 9 und höher wird der Userspace-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
Kill-Strategien
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 Speicherdruck als abnormal angesehen und behoben werden, bevor er sich auf die Gesamtleistung auswirkt.
Sie können die Beendigungsstrategie mit der Property ro.config.low_ram konfigurieren.
Der Userspace-lmkd unterstützt auch einen Legacy-Modus, in dem er Kill-Entscheidungen mit denselben Strategien wie der LMK-Treiber im Kernel trifft (d. h. Schwellenwerte für kostenlosen Arbeitsspeicher und Dateicache). Wenn Sie den alten 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 Speicher 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 die kritische Stufe aktivieren. | false
|
ro.lmk.upgrade_pressure
|
Der maximale mem_pressure, bei dem das Niveau angehoben wird, weil das System zu viel auslagert.
|
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 einem Kill, nach dem kein weiterer Kill 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 wurde 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).
- Patches zur Unterstützung von PIDFD einfügen (Backports sind in den Android Common-Kernels 4.9, 4.14 und 4.19 verfügbar).
- Auf Geräten mit wenig Arbeitsspeicher sollten Sie Speicher-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 Speicherplatz 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 Arbeitsspeicherausfall 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-Schwellenwert in Millisekunden zum Auslösen kritischer Speicherbenachrichtigungen. Wenn das Gerät Benachrichtigungen über kritischen Speichermangel zu spät erhält, verringern Sie diesen Wert, um frühere Benachrichtigungen 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“ diesen Wert überschreitet, 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 gesamten 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 reduziert 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 Strategie zum Beenden von Prozessen.
| 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-space-hungrig gilt. Wenn `lmkd` Prozesse beendet, obwohl noch viel Speicherplatz im Swap-Speicher 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 |
|