Speicherkiller

Der Low-Memory Killer Daemon (LMKD) von Android überwacht den Arbeitsspeicherstatus eines laufenden Android-Systems und reagiert auf eine hohe Arbeitsspeicherauslastung, indem er die am wenigsten wichtigen Prozesse beendet. Android Vitals erfasst und meldet vom Nutzer wahrgenommene LMK-Beendigungen in der Google Play Console, damit Sie Probleme mit der Arbeitsspeicherauslastung erkennen können, die sich auf Ihre Nutzer auswirken.

LMK-Messwert in Android Vitals

Mit Android Vitals können Sie die LMK-Rate Ihrer App im Blick behalten und verbessern. Android Vitals misst nur eine LMK-Rate: die vom Nutzer wahrgenommene LMK-Rate.

Der Messwert gibt den Prozentsatz der aktiven Nutzer pro Tag an, bei denen mindestens ein vom Nutzer wahrgenommener LMK aufgetreten ist. Ein vom Nutzer wahrgenommener LMK ist ein LMK, den der Nutzer wahrscheinlich bemerkt hat. Dazu gehören zum Beispiel LMKs, die auftreten, wenn in Ihrer App eine Aktivität angezeigt oder sie als Dienst im Vordergrund ausgeführt wird. Diese Beendigungen führen zu einem sofortigen, nicht ordnungsgemäßen Beenden des Prozesses. Für den Endnutzer sieht es so aus, als wäre die App abgestürzt. Dabei werden oft die standardmäßigen Mechanismen zum Speichern des Status im Lebenszyklus umgangen, was dazu führt, dass der Fortschritt des Nutzers verloren geht.

Android Vitals konzentriert sich auf diese Prozessbeendigungen, da sie ein zuverlässiger Indikator für Probleme bei der Speicherverwaltung sind. Eine LMK-Rate von über 1 % weist auf einen kritischen Bedarf an sofortigen Maßnahmen hin. Eine niedrigere LMK-Rate bedeutet jedoch nicht unbedingt, dass die Arbeitsspeichernutzung der App in Ordnung ist. Diese niedrigere Rate kann bedeuten, dass der LMK-Daemon häufig Prozesse beendet, während sie sich im Hintergrund befinden. Dadurch wird die Leistung beim „Warmstart“ und die Flüssigkeit beim Multitasking beeinträchtigt.

Sie finden den Messwert im Abschnitt Stabilität in Android Vitals:

Abbildung 1: Rufen Sie in Android Vitals die vom Nutzer wahrgenommene LMK-Rate auf.

Wie bei ähnlichen Vitalparametern wie ANRs und Abstürzen können Sie die Messwerte filtern, mit denen Ihrer Mitbewerber vergleichen oder die Änderung des Messwerts über einen langen Zeitraum (bis zu 3 Jahre) beobachten. Daten sind für bestehende Apps ab dem 28. Januar 2025 verfügbar.

Abbildung 2. Übersicht über die LMK-Rate in Android Vitals.

Funktionsweise des Low Memory Killer-Daemons

Die Android-Plattform basiert auf der Prämisse, dass ungenutzter Speicher verschwendeter Speicher ist. Android versucht, immer den gesamten verfügbaren Arbeitsspeicher zu nutzen. Beispielsweise werden Apps nach dem Schließen im Arbeitsspeicher behalten, damit der Nutzer schnell wieder zu ihnen wechseln kann. Aus diesem Grund laufen Android-Geräte oft mit sehr wenig verfügbarem Arbeitsspeicher (siehe Arbeitsspeicherzuweisung zwischen Prozessen).

Um zu entscheiden, welcher Prozess beendet werden soll, wenn der verfügbare Arbeitsspeicher knapp wird, verwendet der Low-Memory-Killer-Daemon (LMK) einen Out-of-Memory-Score namens oom_adj_score, um die laufenden Prozesse zu priorisieren. Prozesse mit einer hohen Punktzahl werden zuerst beendet. Hintergrund-Apps werden zuerst beendet, Systemprozesse zuletzt. In der folgenden Tabelle sind die LMK-Bewertungskategorien von hoch bis niedrig aufgeführt. Elemente in der Kategorie mit der höchsten Punktzahl in Zeile 1 werden zuerst beendet:

Android-Prozesse, sortiert von der höchsten bis zur niedrigsten Punktzahl: Hintergrund-Apps, vorherige App, Start-App, Dienste, wahrnehmbare Apps, App im Vordergrund, persistente Apps, System-Apps und native Apps.
Abbildung 3. Android-Prozesse, wobei die höchsten Werte oben und die niedrigsten unten stehen.

Tools für das Arbeitsspeicher-Profiling

Mit den folgenden Tools können Sie Speicherprobleme auf folgende Weise finden und diagnostizieren:

  • Hier siehst du, wie deine App im Laufe der Zeit Speicher zuweist. Sie finden dort ein Echtzeitdiagramm, das zeigt, wie viel Arbeitsspeicher Ihre App verwendet, wie viele Java-Objekte zugewiesen sind und wann die automatische Speicherbereinigung erfolgt.
  • Initiieren Sie Speicherbereinigungsereignisse und erstellen Sie einen Snapshot des Java-Heaps, während Ihre Anwendung ausgeführt wird.
  • Zeichnen Sie die Arbeitsspeicherzuweisungen Ihrer App auf, prüfen Sie alle zugewiesenen Objekte und rufen Sie den Stacktrace für jede Zuweisung auf.

Wenn dein Spiel auf einer nativen Engine ausgeführt wird, verwende HWAddress Sanitizer, um die native Arbeitsspeicherzuweisung zu debuggen.

Speicher-Profiler von Android Studio

Android Studio bietet den Speicher-Profiler als Komponente des Android Profiler an. Mit ihm können Sie Speicherlecks und Memory Churn erkennen, die zu Ruckeln, Einfrieren und sogar App-Abstürzen führen können. Der Profiler zeigt ein Echtzeitdiagramm der Arbeitsspeichernutzung Ihrer App. Sie können damit einen Heap-Dump erfassen, die automatische Speicherbereinigung erzwingen und die Arbeitsspeicherzuweisung verfolgen.

Android Studio-Speicher-Profiler mit globalen JNI-Referenzen im Heap.
Abbildung 4. Globale JNI-Referenzen im Speicher-Profiler von Android Studio ansehen

Unity-Tools zur Speicherprofilerstellung

Wenn Sie Ihre Apps mit der Unity Engine erstellen, können Sie der Anleitung zur Speicherprofilerstellung für Unity folgen. Unity bietet zwei Tools, mit denen Sie die Speichernutzung in Ihrer Anwendung in Unity analysieren können.

Das erste ist das Speicher-Profiler-Modul, ein integrierter Profiler, der grundlegende Informationen darüber liefert, wo Ihre Anwendung Speicher verwendet.

Das Speichermodul zeigt Arbeitsspeicherzuweisungen wie Texturspeicher und Mesh-Speicher an.
Abbildung 5. Unity Profiler-Fenster mit ausgewähltem Modul Memory.

Das zweite Tool ist das Speicher-Profiler-Paket, ein Unity-Paket, das Sie Ihrem Projekt hinzufügen können. Das Paket fügt dem Unity-Editor ein zusätzliches Speicher-Profiler-Fenster hinzu. Mit dem Speicher-Profiler können Sie die Speichernutzung in Ihrer Anwendung noch detaillierter analysieren. Sie können Snapshots speichern und vergleichen, um Speicherlecks zu finden, oder das Speicherlayout aufrufen, um Probleme mit der Speicherfragmentierung zu finden.

Unity Speicher-Profiler-Fenster mit einer Aufschlüsselung des Arbeitsspeicher-Snapshots.
Abbildung 6: Arbeitsspeicher-Snapshot mit dem Fenster „Speicher-Profiler“ analysieren

Informationen zu Android-spezifischen Unity-Workflows finden Sie unter Arbeitsspeichernutzung mit Unity-Tools prüfen, Arbeitsspeichernutzung in Unity optimieren und LMKs für Unity-Spiele debuggen.

Unreal Memory Insights

In Apps, die mit der Unreal Engine erstellt wurden, können Sie mit Unreal Memory Insights detaillierte Informationen zur Arbeitsspeicherzuweisung und -freigabe aufrufen, einschließlich der LLM-Tags (Low Level Memory) und Aufrufstacks, die mit Speicherblöcken verknüpft sind.

Das Abfragesystem von Memory Insights kann jederzeit Live-Zuweisungen finden, Änderungen bei der Speichernutzung erkennen, Speicherlecks lokalisieren und kurzfristige von langfristigen Zuweisungen unterscheiden.

Ab UE 5.4 unterstützt Memory Insights das Memory Tracing mit Callstacks für Android-Projekte.

Tracker für Speicherstatistiken mit Diagramm zum Hauptspeicher, Anzahl der Live-Zuweisungen und Anzahl der Zuweisungs-/Freigabeereignisse.
Abbildung 7. Memory Insights-Tracker von Unreal

Informationen zu Android-spezifischen Unreal-Workflows findest du unter Speichernutzung mit Unreal prüfen und Speichernutzung in Unreal optimieren.

Statistiken zu geringem Arbeitsspeicher

Android bietet Callbacks und APIs, mit denen du die Speichernutzung deines Spiels reduzieren und feststellen kannst, warum vorherige Spielausführungen beendet wurden.

Callbacks

Registrieren Sie sich nicht für verworfene Trim-Callbacks. Android bietet keine APIs, um Ereignisse mit hohem nativem Arbeitsspeicherdruck zu erkennen, bevor das System Arbeitsspeicher freigibt. Außerdem haben sich detaillierte Callbacks zum Kürzen des Arbeitsspeichers (TRIM_MEMORY_RUNNING_*) nicht als wirksam erwiesen, um das Beenden von Prozessen aufgrund von Speichermangel zu verhindern. Daher wurden in Android alle Trim-Level außer TRIM_MEMORY_UI_HIDDEN und TRIM_MEMORY_BACKGROUND eingestellt. Verwenden Sie diese verbleibenden Callbacks oder die entsprechenden Lebenszyklus-Callbacks der Engine, z. B. OnApplicationPause von Unity und ApplicationWillEnterBackgroundDelegate von Unreal, um UI- und Hilfsressourcen freizugeben, wenn Ihr Spiel in den Hintergrund verschoben wird. Details zur Implementierung finden Sie unter Arbeitsspeicher in Spielen reduzieren.

Spiel beenden

Android versucht, den gesamten verfügbaren Arbeitsspeicher zum Zwischenspeichern von Apps und Spielen zu verwenden, damit sie schnell geladen werden (was die Nutzerfreundlichkeit verbessert). Wenn der Arbeitsspeicher jedoch knapp wird, beendet das System die speicherintensivsten Apps und Spiele, um Arbeitsspeicher für den normalen Gerätebetrieb freizugeben.

Informationen, Statistiken und Best Practices für eine bessere Speichernutzung bei Spielen:

  • ApplicationExitInfo verwenden: Diese API gibt den Grund zurück, warum die vorherige Spielausführung vom Android-System beendet wurde. Verwende ApplicationExitInfo, um zu prüfen, ob ein niedriger Arbeitsspeicher (REASON_LOW_MEMORY) oder die Beendigung durch den Arbeitsspeicherbegrenzer (REASON_MEMORY_LIMITER) der Grund für das Beenden eines vorherigen Prozesses war (siehe ApplicationExitInfo für Spiele). Prüfen Sie, ob das Spiel aufgrund von Arbeitsspeicherauslastung beendet wurde, damit es so optimiert werden kann, dass es auf diesem Gerät weniger Arbeitsspeicher benötigt.
  • Physischer RAM insgesamt: Damit Spiele im Vordergrund nicht beendet werden und die Leistung des Geräts berücksichtigt wird, solltest du den gesamten physischen RAM pro Gerät genau prüfen und die Speichernutzung des Spiels entsprechend anpassen. Wenn du verhindern möchtest, dass Apps kurz nach dem Verschieben in den Hintergrund beendet werden (damit der Spieler Multitasking nutzen kann), verwende die Trim-Callbacks (insbesondere TRIM_MEMORY_UI_HIDDEN), um die Speichernutzung deines Spiels zu reduzieren.

Zusätzliche Ressourcen