Der Android-Low-Memory-Killer-Daemon-Prozess ( lmkd
) überwacht den Speicherstatus eines laufenden Android-Systems und reagiert auf hohen Speicherdruck, indem er die am wenigsten wichtigen Prozesse beendet, um die Systemleistung auf einem akzeptablen Niveau zu halten.
Über Gedächtnisdruck
Bei einem Android-System, auf dem mehrere Prozesse parallel ausgeführt werden, kann es zu Situationen kommen, in denen der Systemspeicher erschöpft ist und Prozesse, die mehr Speicher benötigen, spürbare Verzögerungen erfahren. Speicherdruck , ein Zustand, in dem dem System der Speicher knapp wird, erfordert, dass Android Speicher freigibt (um den Druck zu verringern), indem unwichtige Prozesse gedrosselt oder beendet werden, Prozesse aufgefordert werden, nicht kritische zwischengespeicherte Ressourcen freizugeben usw.
In der Vergangenheit hat Android den Systemspeicherdruck mithilfe eines LMK-Treibers (Low Memory Killer) im Kernel überwacht, einem starren Mechanismus, der von fest codierten Werten abhängt. Ab Kernel 4.12 wird der LMK-Treiber aus dem Upstream-Kernel entfernt und der Userspace lmkd
führt Speicherüberwachungs- und Prozessbeendigungsaufgaben durch.
Informationen zum Druckstillstand
Android 10 und höher unterstützen einen neuen lmkd
Modus, der PSI-Monitore (Kernel Pressure Stall Information) zur Speicherdruckerkennung verwendet. Das PSI-Patchset im Upstream-Kernel (zurückportiert auf die Kernel 4.9 und 4.14) misst die Zeitspanne, um die Aufgaben aufgrund von Speichermangel verzögert werden. Da sich diese Verzögerungen direkt auf das Benutzererlebnis auswirken, stellen sie eine praktische Messgröße zur Bestimmung des Schweregrads der Speicherauslastung dar. Der Upstream-Kernel enthält auch PSI-Monitore, die es privilegierten Userspace-Prozessen (wie lmkd
) ermöglichen, Schwellenwerte für diese Verzögerungen festzulegen und Ereignisse vom Kernel zu abonnieren, wenn ein Schwellenwert überschritten wird.
PSI-Monitore im Vergleich zu Vm-Drucksignalen
Da die vmpressure
Signale (die vom Kernel zur Speicherdruckerkennung generiert und von lmkd
verwendet werden) häufig zahlreiche Fehlalarme enthalten, muss lmkd
eine Filterung durchführen, um festzustellen, ob der Speicher tatsächlich unter Druck steht. Dies führt zu unnötigen lmkd
Wakeups und der Nutzung zusätzlicher Rechenressourcen. Die Verwendung von PSI-Monitoren führt zu einer genaueren Speicherdruckerkennung und minimiert den Filteraufwand.
Verwenden Sie PSI-Monitore
Um PSI-Monitore anstelle von vmpressure
Ereignissen zu verwenden, konfigurieren Sie die Eigenschaft ro.lmk.use_psi
. Der Standardwert ist true
, wodurch PSI-Monitore der Standardmechanismus zur Speicherdruckerkennung für lmkd
sind. Da PSI-Monitore Kernel-Unterstützung erfordern, muss der Kernel die PSI-Backport-Patches enthalten und mit aktivierter PSI-Unterstützung kompiliert werden ( CONFIG_PSI=y
).
Nachteile des LMK-Treibers im Kernel
Android veraltet den LMK-Treiber aufgrund einer Reihe von Problemen, darunter:
- Geräte mit geringem RAM mussten aggressiv optimiert werden und würden selbst dann bei Workloads mit großem dateigestützten aktiven Seitencache eine schlechte Leistung erbringen. Die schlechte Leistung führte zu Prügel und keinen Kills.
- Der LMK-Kerneltreiber stützte sich auf Beschränkungen des freien Speichers, ohne Skalierung basierend auf der Speicherauslastung.
- Aufgrund der Starrheit des Designs haben Partner den Treiber oft so angepasst, dass er auf ihren Geräten funktioniert.
- Der LMK-Treiber war in die Slab-Shrinker-API eingebunden, die nicht für schwere Vorgänge wie die Suche nach Zielen und deren Tötung konzipiert war, was den
vmscan
Prozess verlangsamte.
Userspace lmkd
Der Userspace- lmkd
implementiert die gleiche Funktionalität wie der In-Kernel-Treiber, nutzt jedoch vorhandene Kernel-Mechanismen, um den Speicherdruck zu erkennen und abzuschätzen. Zu diesen Mechanismen gehören die Verwendung von Kernel-generierten vmpressure
Ereignissen oder PSI-Monitoren (Pressure Stall Information), um Benachrichtigungen über den Speicherdruck zu erhalten, und die Verwendung von Speicher-Cgroup-Funktionen, um die jedem Prozess zugewiesenen Speicherressourcen basierend auf der Prozesswichtigkeit zu begrenzen.
Verwenden Sie Userspace lmkd in Android 10
In Android 9 und höher wird Userspace lmkd
aktiviert, wenn kein kernelinterner LMK-Treiber erkannt wird. Da Userspace lmkd
Kernel-Unterstü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
Tötungsstrategien
Userspace lmkd
unterstützt Kill-Strategien basierend auf vmpressure
Ereignissen oder PSI-Monitoren, deren Schweregrad und anderen Hinweisen wie der Swap-Nutzung. Die Tötungsstrategien unterscheiden sich zwischen Geräten mit wenig Speicher und Geräten mit hoher Leistung:
- Auf Geräten mit wenig Speicher sollte das System im normalen Betriebsmodus einen höheren Speicherdruck tolerieren.
- Auf Hochleistungsgeräten sollte die Speicherauslastung als ungewöhnliche Situation betrachtet und behoben werden, bevor sie sich auf die Gesamtleistung auswirkt.
Sie können die Kill-Strategie mithilfe der Eigenschaft ro.config.low_ram
konfigurieren. Einzelheiten finden Sie unter Konfiguration mit geringem RAM .
Userspace lmkd
unterstützt auch einen Legacy-Modus, in dem es Kill-Entscheidungen mit denselben Strategien wie der LMK-Treiber im Kernel trifft (d. h. Schwellenwerte für freien Speicher und Datei-Cache). Um den Legacy-Modus zu aktivieren, setzen Sie die Eigenschaft ro.lmk.use_minfree_levels
auf true
.
Konfigurieren Sie lmkd
Konfigurieren Sie lmkd
für ein bestimmtes Gerät mithilfe der folgenden Eigenschaften.
Eigentum | Verwenden | Standard |
---|---|---|
ro.config.low_ram | Geben Sie an, ob es sich bei dem Gerät um ein Gerät mit wenig RAM oder um ein Hochleistungsgerät handelt. | false |
ro.lmk.use_psi | Verwenden Sie PSI-Monitore (anstelle von vmpressure Ereignissen). | true |
ro.lmk.use_minfree_levels | Verwenden Sie Schwellenwerte für freien Speicher und Dateicache, um Entscheidungen zum Abbruch von Prozessen zu treffen (d. h. passen Sie sie an die Funktionalität des LMK-Treibers im Kernel an). | false |
ro.lmk.low | Der minimale oom_adj Score für Prozesse, die bei einem niedrigen vmpressure Level beendet werden können. | 1001 (deaktiviert) |
ro.lmk.medium | Der minimale oom_adj Score für Prozesse, die bei mittlerem vmpressure Level beendet werden können. | 800 (zwischengespeicherte oder nicht wesentliche Dienste) |
ro.lmk.critical | Der minimale oom_adj Score für Prozesse, die bei einem kritischen vmpressure Level beendet werden können. | 0 (jeder Prozess) |
ro.lmk.critical_upgrade | Aktivieren Sie das Upgrade auf die kritische Ebene. | false |
ro.lmk.upgrade_pressure | Der maximale mem_pressure , bei dem die Ebene aktualisiert wird, weil das System zu viel austauscht. | 100 (deaktiviert) |
ro.lmk.downgrade_pressure | Der minimale mem_pressure , bei dem ein vmpressure Ereignis ignoriert wird, da noch genügend freier Speicher verfügbar ist. | 100 (deaktiviert) |
ro.lmk.kill_heaviest_task | Töten Sie die schwerste in Frage kommende Aufgabe (beste Entscheidung) im Vergleich zu jeder in Frage kommenden Aufgabe (schnelle Entscheidung). | true |
ro.lmk.kill_timeout_ms | Dauer in Millisekunden nach einem Kill, wenn kein weiterer Kill durchgeführt wird. | 0 (deaktiviert) |
ro.lmk.debug | Aktivieren Sie lmkd Debug-Protokolle. | false |
Beispielhafte 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
Android 11 verbessert den lmkd
durch die Einführung einer neuen Tötungsstrategie. Die Killing-Strategie nutzt einen PSI-Mechanismus zur Speicherdruckerkennung, der in Android 10 eingeführt wurde. lmkd
in Android 11 berücksichtigt die Speicherressourcenauslastung und Thrashing, um Speichermangel und Leistungseinbußen zu verhindern. Diese Tötungsstrategie ersetzt frühere Strategien und kann sowohl auf Geräten mit hoher Leistung als auch auf Geräten mit wenig RAM (Android Go) verwendet werden.
Kernel-Anforderungen
Für Android 11-Geräte erfordert lmkd
die folgenden Kernelfunktionen:
- Fügen Sie PSI-Patches hinzu und aktivieren Sie PSI (Backports verfügbar in den gängigen Android-Kerneln 4.9, 4.14 und 4.19).
- Fügen Sie PIDFD-Unterstützungspatches hinzu (Backports, die in den gängigen Android-Kerneln 4.9, 4.14 und 4.19 verfügbar sind).
- Schließen Sie für Geräte mit wenig RAM Speicher-Cgroups ein.
Der Kernel muss mit den folgenden Konfigurationseinstellungen kompiliert werden:
CONFIG_PSI=y
Konfigurieren Sie lmkd in Android 11
Die Memory-Killing-Strategie in Android 11 unterstützt die unten aufgeführten Einstellknöpfe und Standardeinstellungen. Diese Funktionen funktionieren sowohl auf Hochleistungsgeräten als auch auf Geräten mit wenig RAM.
Eigentum | Verwenden | Standard | |
---|---|---|---|
Hochleistung | Wenig RAM | ||
ro.lmk.psi_partial_stall_ms | Der teilweise PSI-Stallschwellenwert in Millisekunden zum Auslösen einer Benachrichtigung über wenig Arbeitsspeicher. Wenn das Gerät Benachrichtigungen über Speicherauslastung zu spät erhält, verringern Sie diesen Wert, um frühere Benachrichtigungen auszulösen. Wenn unnötigerweise Benachrichtigungen über Speicherauslastung ausgelöst werden, erhöhen Sie diesen Wert, um das Gerät weniger empfindlich gegenüber Störungen zu machen. | 70 | 200 |
ro.lmk.psi_complete_stall_ms | Der vollständige PSI-Stallschwellenwert in Millisekunden zum Auslösen kritischer Speicherbenachrichtigungen. Wenn das Gerät Benachrichtigungen über kritische Speicherauslastung zu spät erhält, verringern Sie diesen Wert, um frühere Benachrichtigungen auszulösen. Wenn unnötigerweise Benachrichtigungen über kritische Speicherauslastung ausgelöst werden, erhöhen Sie diesen Wert, um das Gerät weniger empfindlich gegenüber Störungen zu machen. | 700 | |
ro.lmk.thrashing_limit | Die maximale Anzahl an Workingset-Refaults wird als Prozentsatz der gesamten dateigestützten Seitencache-Größe angegeben. Arbeitssatz-Refaults über diesem Wert bedeuten, dass davon ausgegangen wird, dass das System seinen Seitencache überlastet. Wenn die Leistung des Geräts während der Speicherauslastung beeinträchtigt wird, verringern Sie den Wert, um Thrashing zu begrenzen. Wenn die Leistung des Geräts aus Thrashing-Gründen unnötig beeinträchtigt wird, erhöhen Sie den Wert, um mehr Thrashing zu ermöglichen. | 100 | 30 |
ro.lmk.thrashing_limit_decay | Der Thrashing-Schwellenwertabfall, ausgedrückt als Prozentsatz des ursprünglichen Schwellenwerts, wird verwendet, um den Schwellenwert zu senken, wenn sich das System nicht erholt, selbst nach einem Kill. Wenn kontinuierliches Prügeln zu unnötigen Kills führt, 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 Speicher als Prozentsatz des gesamten auswechselbaren Speichers. Wenn der ausgelagerte Speicher diesen Grenzwert überschreitet, bedeutet das, dass das System den größten Teil seines auswechselbaren Speichers ausgelagert hat und immer noch unter Druck steht. Dies kann passieren, wenn nicht austauschbare Zuweisungen Speicherdruck erzeugen, der nicht durch Auslagern entlastet werden kann, da der größte Teil des auswechselbaren Speichers bereits ausgelagert ist. Der Standardwert ist 100, wodurch diese Prüfung effektiv deaktiviert wird. Wenn die Leistung des Geräts während der Speicherauslastung beeinträchtigt wird, während die Swap-Nutzung hoch ist und der freie Swap-Level nicht auf ro.lmk.swap_free_low_percentage sinkt, verringern Sie den Wert, um die Swap-Nutzung zu begrenzen. | 100 | 100 |
Die folgenden alten Stimmknöpfe funktionieren auch mit der neuen Tötungsstrategie.
Eigentum | Verwenden | Standard | |
---|---|---|---|
Hochleistung | Wenig RAM | ||
ro.lmk.swap_free_low_percentage | Der Anteil des freien Swaps als Prozentsatz des gesamten Swap-Speicherplatzes. „lmkd“ verwendet diesen Wert als Schwellenwert dafür, wann das System als Swap-Space-hungrig betrachtet werden soll. Wenn „lmkd“ abstürzt, während im Swap zu viel Platz vorhanden ist, verringern Sie den Prozentsatz. Wenn „lmkd“-Kills zu spät erfolgen und OOM-Kills möglich sind, erhöhen Sie den Prozentsatz. | 20 | 10 |
ro.lmk.debug | Dadurch werden „lmkd“-Debug-Protokolle aktiviert. Aktivieren Sie das Debuggen während der Optimierung. | false |