Der Android-Low-Memory-Killer-Daemon (lmkd
) überwacht den Arbeitsspeicherstatus eines laufenden Android-Systems und reagiert auf einen hohen Arbeitsspeicherdruck, indem er die am wenigsten wichtigen Prozesse beendet, um die Leistung des Systems auf einem akzeptablen Niveau zu halten.
Arbeitsspeicherdruck
Bei einem Android-System, auf dem mehrere Prozesse parallel ausgeführt werden, kann es vorkommen, dass der Systemspeicher aufgebraucht ist und Prozesse, die mehr Speicher benötigen, merkliche Verzögerungen aufweisen. Bei Speicherdruck, einem Zustand, in dem dem System nicht genügend Arbeitsspeicher zur Verfügung steht, muss Android Speicher freigeben, um den Druck zu verringern. Dazu werden unwichtige Prozesse gedrosselt oder beendet und Prozesse aufgefordert, nicht kritische Ressourcen im Cache freizugeben.
Bisher wurde der Systemspeicherbedarf unter Android mit einem Low Memory Killer (LMK)-Treiber im Kernel überwacht. Dieser starre Mechanismus basiert auf hartcodierten Werten. Ab Kernel 4.12 wurde der LMK-Treiber aus dem Upstream-Kernel entfernt und der Nutzerbereich lmkd
führt die Arbeitsspeicherüberwachung und das Beenden von Prozessen aus.
Informationen zum Druckabfall
Android 10 und höher unterstützen einen neuen lmkd
-Modus, bei dem PSI-Monitore (Kernel Pressure Stall Information) zur Erkennung von Arbeitsspeichermangel verwendet werden. Das PSI-Patch-Set im Upstream-Kernel (zurückportiert auf die Kernel 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 die Schwere des Speicherdrucks zu bestimmen. Der Upstream-Kernel enthält auch PSI-Monitore, mit denen privilegierte Prozesse im Userspace (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) häufig zahlreiche Fehlalarme enthalten, muss lmkd
eine Filterung durchführen, um festzustellen, ob der Arbeitsspeicher wirklich ausgelastet ist.
Dies führt zu unnötigen lmkd
-Aufweckvorgängen und zur Verwendung zusätzlicher Rechenressourcen. Die Verwendung von PSI-Monitoren führt zu einer genaueren Erkennung des Arbeitsspeicherdrucks und minimiert den Filteroverhead.
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-Monitore sind dann der Standardmechanismus zur Erkennung von Speichermangel für lmkd
. Da PSI-Monitore Kernelunterstützung erfordern, muss der Kernel die PSI-Backport-Patches enthalten und mit aktivierter PSI-Unterstützung (CONFIG_PSI=y
) kompiliert werden.
Nachteile eines LMK-Treibers im Kernel
Android stellt den LMK-Treiber aufgrund einer Reihe von Problemen ein, darunter:
- Geräte mit wenig RAM mussten aggressiv optimiert werden und selbst dann schnitten sie bei Arbeitslasten mit einem großen aktiven Datei-basierten Auslagerungsbereich schlecht ab. Die schlechte Leistung führte zu Auslastungsspitzen und keinen Kills.
- Der LMK-Kerneltreiber basierte auf Grenzwerten für kostenlosen Arbeitsspeicher, ohne Skalierung basierend auf der Arbeitsspeicherauslastung.
- Aufgrund der Starrheit des Designs haben Partner den Treiber oft so angepasst, dass er auf ihren Geräten funktioniert.
- Der LMK-Treiber war an die Slab-Shrinker-API angehängt, die nicht für umfangreiche Vorgänge wie die Suche nach Zielen und deren Beendigung konzipiert war. Dies führte zu einer Verlangsamung des
vmscan
-Prozesses.
Userspace lmkd
Der Userspace-lmkd
implementiert dieselben Funktionen wie der In-Kernel-Treiber, verwendet aber vorhandene Kernelmechanismen, um den Arbeitsspeicherdruck zu erkennen und zu schätzen. Dazu gehören die Verwendung von kernelgenerierten vmpressure
-Ereignissen oder PSI-Monitoren (Pressure Stall Information), um Benachrichtigungen über den Arbeitsspeicherdruck zu erhalten, und die Verwendung von Arbeitsspeicher-Cgroup-Funktionen, um die Arbeitsspeicherressourcen zu begrenzen, die jedem Prozess basierend auf der Prozessbedeutung zugewiesen werden.
Userspace lmkd in Android 10 verwenden
Unter Android 9 und höher wird der Nutzerbereich lmkd
aktiviert, wenn kein LMK-Treiber im Kernel erkannt wird. Da der Userspace lmkd
Kernelunterstützung für Speicher-Cgroups erfordert, muss der Kernel mit den folgenden Konfigurationseinstellungen kompiliert werden:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
Strategien beenden
Der Userspace lmkd
unterstützt Kill-Strategien, die auf vmpressure
-Ereignissen oder PSI-Monitoren, ihrer Schwere und anderen Hinweisen wie der Auslastung des Auslagerungsbereichs basieren. Die Kill-Strategien unterscheiden sich zwischen Geräten mit wenig Arbeitsspeicher und Geräten mit hoher Leistung:
- Auf Geräten mit wenig Arbeitsspeicher sollte das System einen höheren Arbeitsspeicherausfall als normalen Betriebsmodus tolerieren.
- Auf Hochleistungsgeräten sollte eine hohe Speicherauslastung als anormal betrachtet und behoben werden, bevor sie sich auf die Gesamtleistung auswirkt.
Sie können die Kill-Strategie mithilfe der Property ro.config.low_ram
konfigurieren. Weitere Informationen finden Sie unter Konfiguration mit wenig RAM.
Userspace lmkd
unterstützt auch einen Legacy-Modus, in dem Kill-Entscheidungen mit denselben Strategien wie der LMK-Treiber im Kernel getroffen werden (d. h. Grenzwerte für kostenlosen Arbeitsspeicher und Dateicache). Wenn Sie den alten Modus aktivieren möchten, legen Sie für die Property ro.lmk.use_minfree_levels
den Wert true
fest.
lmkd konfigurieren
Konfigurieren Sie lmkd
mithilfe der folgenden Eigenschaften für ein bestimmtes Gerät.
Attribut | Verwenden | Standard |
---|---|---|
ro.config.low_ram
|
Geben Sie an, ob es sich um ein Gerät mit wenig RAM oder um 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. stimmen Sie die Funktion mit dem LMK-Treiber im Kernel ab). | false
|
ro.lmk.low
|
Der Mindestwert für oom_adj für Prozesse, die bei niedrigem vmpressure -Wert beendet werden können.
|
1001 (deaktiviert) |
ro.lmk.medium
|
Der Mindestwert für oom_adj für Prozesse, die auf mittlerer vmpressure -Ebene beendet werden können.
|
800 (im Cache gespeicherte oder nicht notwendige Dienste) |
ro.lmk.critical
|
Der Mindestwert für oom_adj für Prozesse, die bei kritischer vmpressure -Ebene beendet werden können.
|
0 (beliebiger Prozess) |
ro.lmk.critical_upgrade
|
Aktivieren Sie das Upgrade auf die kritische Stufe. | false
|
ro.lmk.upgrade_pressure
|
Der maximale mem_pressure , bei dem das Niveau erhöht wird, weil das System zu viel auslagert.
|
100 (deaktiviert) |
ro.lmk.downgrade_pressure
|
Der Mindestwert von mem_pressure , bei dem ein vmpressure -Ereignis ignoriert wird, da noch genügend kostenloser Arbeitsspeicher verfügbar ist.
|
100 (deaktiviert) |
ro.lmk.kill_heaviest_task
|
Die größte infrage kommende Aufgabe beenden (beste Entscheidung) oder eine beliebige infrage kommende Aufgabe (schnelle Entscheidung). | false
|
ro.lmk.kill_timeout_ms
|
Dauer in Millisekunden nach einem Kill, wenn kein weiterer Kill ausgeführt wird. | 0 (deaktiviert) |
ro.lmk.debug
|
Aktivieren Sie lmkd -Fehlerbehebungsprotokolle.
|
false
|
Beispiel für eine 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
Userspace-lmkd in Android 11
In Android 11 wurde die lmkd
durch eine neue Beendigungsstrategie verbessert. Die Beendigungsstrategie verwendet einen PSI-Mechanismus zur Erkennung von Arbeitsspeichermangel, der in Android 10 eingeführt wurde. lmkd
in Android 11 berücksichtigt die Nutzung von Arbeitsspeicherressourcen und das Auslagern von Speicher, um einen Speichermangel und eine Leistungsminderung zu vermeiden.
Diese Strategie ersetzt vorherige Strategien und kann sowohl auf Hochleistungsgeräten als auch auf Geräten mit wenig RAM (Android Go) verwendet werden.
Kernelanforderungen
Für Android 11-Geräte sind für lmkd
die folgenden Kernelfunktionen erforderlich:
- Fügen Sie PSI-Patches hinzu und aktivieren Sie PSI (Backports verfügbar in den Android Common Kernels 4.9, 4.14 und 4.19).
- Fügen Sie PIDFD-Unterstützungs-Patches hinzu (Backports in den Android Common Kernels 4.9, 4.14 und 4.19 verfügbar).
- Fügen Sie für Geräte mit wenig RAM Speicher-Cgroups hinzu.
Der Kernel muss mit den folgenden Konfigurationseinstellungen kompiliert werden:
CONFIG_PSI=y
lmkd in Android 11 konfigurieren
Die Strategie zum Beenden von Prozessen in Android 11 unterstützt die unten aufgeführten Optionen und Standardeinstellungen. Diese Funktionen funktionieren sowohl auf leistungsstarken als auch auf Geräten mit wenig RAM.
Attribut | Verwenden | Standard | |
---|---|---|---|
Hohe Leistung | Zu wenig RAM | ||
ro.lmk.psi_partial_stall_ms |
Der partielle PSI-Stall-Schwellenwert in Millisekunden, der eine Benachrichtigung bei niedrigem Arbeitsspeicher auslöst. Wenn das Gerät Benachrichtigungen zu einem hohen Arbeitsspeicherverbrauch zu spät erhält, verringern Sie diesen Wert, um frühere Benachrichtigungen auszulösen. Wenn Benachrichtigungen zu Arbeitsspeichermangel unnötig ausgelöst werden, erhöhen Sie diesen Wert, um das Gerät weniger empfindlich für Störungen zu machen. | 70 |
200 |
ro.lmk.psi_complete_stall_ms |
Der vollständige PSI-Stall-Grenzwert in Millisekunden, der zum Auslösen von Benachrichtigungen zu kritischem Arbeitsspeicher führt. Wenn das Gerät zu spät Benachrichtigungen zu kritischem Arbeitsspeichermangel 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 empfindlich für Störungen zu machen. | 700 |
|
ro.lmk.thrashing_limit |
Die maximale Anzahl der Arbeitssatz-Neuzuordnungen als Prozentsatz der gesamten vom Dateisystem unterstützten Größe des Auslagerungsspeichers. Wenn der Wert für die Arbeitssatzfehler über diesem Wert liegt, wird davon ausgegangen, dass der Auslagerungsbereich des Systems überlastet ist. Wenn die Leistung des Geräts bei Arbeitsspeicherausfall beeinträchtigt wird, verringern Sie den Wert, um das Auslagern zu begrenzen. Wenn die Leistung des Geräts aufgrund von Auslagerung unnötig beeinträchtigt wird, erhöhen Sie den Wert, um mehr Auslagerung zuzulassen. | 100 |
30 |
ro.lmk.thrashing_limit_decay |
Der Schwellenwert für das Überlasten, ausgedrückt als Prozentsatz des ursprünglichen Schwellenwerts, der verwendet wird, um den Schwellenwert zu senken, wenn sich das System nicht erholt, auch nicht nach dem Beenden eines Prozesses. Wenn durch kontinuierliches Auslagern unnötige Prozesse beendet werden, verringern Sie den Wert. Wenn die Reaktion auf kontinuierliches Auslagern nach dem Beenden zu langsam ist, erhöhen Sie den Wert. | 10 |
50 |
ro.lmk.swap_util_max |
Die maximale Größe des ausgelagerten Arbeitsspeichers als Prozentsatz des gesamten auslagerbaren Arbeitsspeichers. Wenn der ausgelagerte Arbeitsspeicher dieses Limit überschreitet, bedeutet das, dass das System den Großteil seines auslagerbaren Arbeitsspeichers ausgelagert hat und immer noch unter Druck steht.
Dies kann passieren, wenn nicht auslagerbare Zuordnungen einen Speicherdruck erzeugen, der nicht durch Auslagerung gelindert werden kann, da der Großteil des auslagerbaren Arbeitsspeichers bereits ausgelagert wurde. Der Standardwert ist 100, wodurch diese Prüfung effektiv deaktiviert wird. Wenn die Leistung des Geräts bei Speichermangel beeinträchtigt wird, die Auslastung des Auslagerungsbereichs hoch ist und der kostenlose Auslagerungsbereich nicht auf ro.lmk.swap_free_low_percentage sinkt, verringern Sie den Wert, um die Auslastung des Auslagerungsbereichs zu begrenzen. |
100 |
100 |
Die folgenden alten Einstellknöpfe funktionieren auch mit der neuen Kill-Strategie.
Attribut | Verwenden | Standard | |
---|---|---|---|
Hohe Leistung | Zu wenig RAM | ||
ro.lmk.swap_free_low_percentage |
Der kostenlose Auslagerungsbereich als Prozentsatz des gesamten Auslagerungsbereichs. `lmkd` verwendet diesen Wert als Grenzwert, ab dem das System als Swap-Speicherplatz knapp betrachtet wird. Wenn `lmkd` Prozesse beendet, obwohl noch zu viel Speicherplatz im Auslagerungsbereich vorhanden ist, verringern Sie den Prozentsatz. Wenn `lmkd`-Kills zu spät erfolgen und es zu OOM-Kills kommt, erhöhen Sie den Prozentsatz. | 20 |
10 |
ro.lmk.debug |
Dadurch werden Debug-Protokolle für `lmkd` aktiviert. Aktivieren Sie die Debug-Funktion während der Optimierung. | false |