Low Memory Killer Daemon

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