Der Android Low Memory Killer Daemon ( lmkd
)-Prozess überwacht den Speicherstatus eines laufenden Android-Systems und reagiert auf hohen Speicherdruck, indem er die am wenigsten wichtigen Prozesse beendet, um die Leistung des Systems auf einem akzeptablen Niveau zu halten.
Über Gedächtnisdruck
Auf 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, merkliche Verzögerungen erfahren. Speicherdruck , ein Zustand, in dem dem System der Speicher ausgeht, erfordert, dass Android Speicher freigibt (um den Druck zu verringern), indem unwichtige Prozesse gedrosselt oder beendet werden, Prozesse aufgefordert werden, unkritische zwischengespeicherte Ressourcen freizugeben, und so weiter.
In der Vergangenheit überwachte Android den Systemspeicherdruck mit einem Kernel-Low-Memory-Killer-Treiber (LMK), einem starren Mechanismus, der von hartcodierten 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 Prozessbeseitigungsaufgaben durch.
Informationen zum Druckabriss
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 Speicherknappheit verzögert werden. Da sich diese Verzögerungen direkt auf die Benutzererfahrung auswirken, stellen sie eine praktische Metrik zur Bestimmung des Schweregrads des Speicherdrucks 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 vmpressure-Signalen
Da die vmpressure
Signale (vom Kernel zur Erkennung des Speicherdrucks generiert und von lmkd
verwendet) häufig zahlreiche falsch positive Ergebnisse enthalten, muss lmkd
eine Filterung durchführen, um festzustellen, ob der Speicher unter echtem Druck steht. Dies führt zu unnötigen lmkd
Aufwecken und der Verwendung zusätzlicher Rechenressourcen. Die Verwendung von PSI-Monitoren führt zu einer genaueren Erkennung des Speicherdrucks und minimiert den Filteraufwand.
Verwendung von PSI-Monitoren
Um PSI-Monitore anstelle von vmpressure
Ereignissen zu verwenden, konfigurieren Sie die Eigenschaft ro.lmk.use_psi
. Der Standardwert ist true
, wodurch PSI den Standardmechanismus der Speicherdruckerkennung für lmkd
. 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 verwirft den LMK-Treiber aufgrund einer Reihe von Problemen, darunter:
- Geräte mit niedrigem RAM mussten aggressiv optimiert werden und zeigten selbst dann eine schlechte Leistung bei Workloads mit großem dateigestütztem aktivem Pagecache. Die schlechte Leistung führte zu Schlägen und keinen Kills.
- Der LMK-Kerneltreiber stützte sich auf Begrenzungen 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 hat sich in die Slab-Shrinker-API eingehängt, die nicht für schwere Operationen wie das Suchen und Töten von Zielen ausgelegt war, was den
vmscan
Prozess verlangsamte.
Userspace lmkd
Der Userspace lmkd
implementiert die gleiche Funktionalität wie der Kernel-Treiber, verwendet 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 Speicherauslastungsniveaus zu erhalten, und die Verwendung von Speicher-cgroup-Funktionen, um die jedem Prozess zugewiesenen Speicherressourcen basierend auf der Prozesswichtigkeit zu begrenzen.
Verwenden von Userspace lmkd in Android 10
In Android 9 und höher wird Userspace lmkd
aktiviert, wenn kein Kernel-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öte Strategien
Userspace lmkd
unterstützt Kill-Strategien basierend auf vmpressure
Ereignissen oder PSI-Monitoren, deren Schweregrad und anderen Hinweisen wie Swap-Nutzung. Kill-Strategien unterscheiden sich zwischen Low-Memory- und High-Performance-Geräten:
- Auf Geräten mit wenig Arbeitsspeicher sollte das System im normalen Betriebsmodus einen höheren Arbeitsspeicherdruck tolerieren.
- Auf Hochleistungsgeräten sollte die Speicherauslastung als anormale Situation angesehen und behoben werden, bevor sie die Gesamtleistung beeinträchtigt.
Sie können die Kill-Strategie mit der Eigenschaft ro.config.low_ram
konfigurieren. Einzelheiten finden Sie unter Low-RAM-Konfiguration .
Userspace lmkd
unterstützt auch einen Legacy-Modus, in dem es Kill-Entscheidungen mit den gleichen Strategien wie der Kernel-LMK-Treiber 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
.
lmkd konfigurieren
Konfigurieren lmkd
für ein bestimmtes Gerät mit den folgenden Eigenschaften.
Eigentum | Benutzen | Standard |
---|---|---|
ro.config.low_ram | Geben Sie an, ob es sich bei dem Gerät um ein Low-RAM- oder 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 Arbeitsspeicher und Datei-Cache, 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 minimale oom_adj Punktzahl für Prozesse, die bei niedrigem vmpressure Level beendet werden können. | 1001 (behindert) |
ro.lmk.medium | Die minimale oom_adj Punktzahl für Prozesse, die bei mittlerem vmpressure Level beendet werden können. | 800 (zwischengespeicherte oder nicht erforderliche Dienste) |
ro.lmk.critical | Die minimale oom_adj Punktzahl für Prozesse, die bei einem kritischen vmpressure Level 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 der Pegel erhöht wird, weil das System zu viel austauscht. | 100 (behindert) |
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 (behindert) |
ro.lmk.kill_heaviest_task | Beenden Sie die schwerste zulässige Aufgabe (beste Entscheidung) gegenüber jeder zulässigen Aufgabe (schnelle Entscheidung). | true |
ro.lmk.kill_timeout_ms | Dauer in Millisekunden nach einem Kill, wenn kein weiterer Kill durchgeführt wird. | 0 (behindert) |
ro.lmk.debug | lmkd Debug-Protokolle. | false |
Beispiel 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 Tötungsstrategie verwendet einen PSI-Mechanismus zur Speicherdruckerkennung, der in Android 10 eingeführt wurde. lmkd
in Android 11 berücksichtigt die Nutzung von Speicherressourcen und Thrashing, um Speichermangel und Leistungseinbußen zu verhindern. Diese Tötungsstrategie ersetzt frühere Strategien und kann sowohl auf Hochleistungs- als auch auf Low-RAM-Geräten (Android Go) verwendet werden.
Kernel-Anforderungen
Für Android 11-Geräte erfordert lmkd
die folgenden Kernel-Features:
- Fügen Sie PSI-Patches hinzu und aktivieren Sie PSI (Backports sind in den allgemeinen Android-Kerneln 4.9, 4.14 und 4.19 verfügbar).
- PIDFD-Support-Patches einbeziehen (Backports verfügbar in den allgemeinen Android-Kerneln 4.9, 4.14 und 4.19).
- 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 von lmkd in Android 11
Die Speicherlöschstrategie in Android 11 unterstützt die unten aufgeführten Tuning-Regler und Standardeinstellungen. Diese Funktionen funktionieren sowohl auf Hochleistungs- als auch auf Low-RAM-Geräten.
Eigentum | Benutzen | Standard | |
---|---|---|---|
Hochleistung | Niedriger Arbeitsspeicher | ||
ro.lmk.psi_partial_stall_ms | Der partielle PSI-Blockierungsschwellenwert in Millisekunden zum Auslösen einer Benachrichtigung über wenig Arbeitsspeicher. Wenn das Gerät Speicherdruckbenachrichtigungen zu spät empfängt, verringern Sie diesen Wert, um frühere Benachrichtigungen auszulösen. Wenn Speicherdruckbenachrichtigungen unnötigerweise ausgelöst werden, erhöhen Sie diesen Wert, um das Gerät weniger empfindlich gegenüber Rauschen zu machen. | 70 | 200 |
ro.lmk.psi_complete_stall_ms | Der vollständige PSI-Blockierungsschwellenwert in Millisekunden zum Auslösen von kritischen 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 Benachrichtigungen über kritische Speicherauslastung unnötigerweise ausgelöst werden, erhöhen Sie diesen Wert, um das Gerät weniger empfindlich gegenüber Rauschen zu machen. | 700 | |
ro.lmk.thrashing_limit | Die maximale Menge des Workingsets wird als Prozentsatz der gesamten dateigestützten Pagecache-Größe angegeben. Workingset-Refaults über diesem Wert bedeuten, dass davon ausgegangen wird, dass das System seinen Pagecache überlastet. Wenn die Leistung des Geräts während des Speicherdrucks beeinträchtigt wird, verringern Sie den Wert, um Thrashing zu begrenzen. Wenn die Leistung des Geräts unnötigerweise durch Thrashing beeinträchtigt wird, erhöhen Sie den Wert, um mehr Thrashing zu ermöglichen. | 100 | 30 |
ro.lmk.thrashing_limit_decay | Der Abfall des Thrash-Schwellenwerts, ausgedrückt als Prozentsatz des ursprünglichen Schwellenwerts, der verwendet wird, um den Schwellenwert zu senken, wenn sich das System nicht erholt, selbst nach einem Kill. Wenn kontinuierliches Thrashing unnötige Kills erzeugt, verringern Sie den Wert. Wenn die Reaktion auf kontinuierliches Schlagen nach einem Kill zu langsam ist, erhöhen Sie den Wert. | 10 | 50 |
ro.lmk.swap_util_max | Die maximale Menge des ausgelagerten Arbeitsspeichers als Prozentsatz des gesamten auslagerungsfähigen Arbeitsspeichers. Wenn der ausgelagerte Speicher über diese Grenze hinauswächst, bedeutet dies, dass das System den größten Teil seines auslagerbaren Speichers ausgelagert hat und immer noch unter Druck steht. Dies kann passieren, wenn nicht austauschbare Zuordnungen Speicherdruck erzeugen, der nicht durch Austauschen entlastet werden kann, da der größte Teil des austauschbaren Speichers bereits ausgelagert ist. Der Standardwert ist 100, wodurch diese Prüfung effektiv deaktiviert wird. Wenn die Leistung des Geräts während des Arbeitsspeicherdrucks beeinträchtigt wird, während die Auslagerungsauslastung hoch ist und die freie Auslagerungsstufe nicht auf ro.lmk.swap_free_low_percentage , verringern Sie den Wert, um die Auslagerungsauslastung zu begrenzen. | 100 | 100 |
Die folgenden alten Tuning-Regler funktionieren auch mit der neuen Tötungsstrategie.
Eigentum | Benutzen | Standard | |
---|---|---|---|
Hochleistung | Niedriger Arbeitsspeicher | ||
ro.lmk.swap_free_low_percentage | Das Niveau des kostenlosen Swaps als Prozentsatz des gesamten Swap-Speicherplatzes. `lmkd` verwendet diesen Wert als Schwellenwert dafür, wann das System als verknappter Auslagerungsspeicher angesehen wird. Wenn `lmkd` abbricht, während zu viel Platz im Swap vorhanden ist, verringern Sie den Prozentsatz. Wenn „lmkd“-Kills zu spät erfolgen, sodass OOM-Kills stattfinden können, erhöhen Sie den Prozentsatz. | 20 | 10 |
ro.lmk.debug | Dies aktiviert `lmkd`-Debug-Protokolle. Debug während der Optimierung aktivieren. | false |