Die Speicheroptimierung ist entscheidend für ein stabiles, leistungsstarkes Spielerlebnis auf Android-Geräten. In diesem Leitfaden wird erläutert, warum Speichereffizienz wichtig ist, wie das Android-Betriebssystem die Speicherlimits für Prozesse verwaltet und welche neuen Speichermesswerte in der Google Play Console verfügbar sind, mit denen Sie die technische Qualität Ihres Spiels im Blick behalten und verbessern können.
Bedeutung der Speicheroptimierung
Die Optimierung des Arbeitsspeichers Ihres Spiels ist wichtig, um die Spielerbindung aufrechtzuerhalten, die Gerätekompatibilität zu erweitern und die Qualitätsstandards der Plattform einzuhalten:
- Kaltstartvermeidung (Nutzerfreundlichkeit und Bindung): Wenn ein Spieler vorübergehend das Spiel verlässt, um beispielsweise auf eine Benachrichtigung zu antworten oder eine Nachricht zu lesen, wird der Spielprozess vom Betriebssystem in den Hintergrund verschoben. Wenn der Speicherbedarf des Spiels im Hintergrund zu hoch ist, priorisiert der Low Memory Killer (LMK) des Systems das Beenden des Spielprozesses, um RAM für Aufgaben im Vordergrund freizugeben. Wenn der Nutzer das Spiel das nächste Mal fortsetzt, muss es statt einer nahtlosen und sofortigen Wiederaufnahme einen langen Kaltstart durchlaufen. Dabei werden umfangreiche Grafikinhalte, Audioinhalte und Binärdateien der Spiel-Engine vollständig aus dem Speicher neu geladen. Wenn Sie die Arbeitsspeichernutzung im Hintergrund niedrig halten, verhindern Sie diese stillen Beendigungen im Hintergrund, behalten den Nutzerstatus bei und sorgen dafür, dass Spieler ihre Sitzung sofort fortsetzen können. Weitere Informationen zum Verhalten des System-LMK finden Sie im Leitfaden Android Vitals – Low Memory Killer.
- Stabilität des Ökosystems und der Geräte: Ineffiziente Arbeitsspeichernutzung und Speicherlecks beeinträchtigen den Gesamtzustand des Systems. Wenn der Systemspeicher knapp ist, steht das System unter starkem Druck, was zu Einbrüchen bei der Framerate, Ruckeln der Benutzeroberfläche und Audioproblemen führt. Wenn die Arbeitsspeicherauslastung zu hoch ist, beendet der Low Memory Killer (LMK) des Systems Hintergrundprozesse aggressiv. Das führt bei anderen Anwendungen zu langsamen Kaltstarts und zum Verlust des Nutzerstatus, wenn Spieler zwischen Aufgaben wechseln.
- Beendigung auf Plattformebene: Ab Android 17 (API-Level 37) beendet das System Prozesse, die zu viel Arbeitsspeicher belegen, proaktiver. Wenn der Speicherbedarf deines Spiels zu hoch ist, kann das Betriebssystem den Prozess abrupt beenden, ohne einen Standard-Stacktrace zu generieren.
- Gerätekompatibilität: Während Flaggschiff-Geräte 12 GB bis 16 GB RAM haben, verwendet ein großer Teil der weltweiten Gaming-Community Geräte mit 4 GB oder 6 GB RAM. Eine ordnungsgemäße Speicherverwaltung sorgt dafür, dass dein Spiel auf allen Hardwarestufen zugänglich und reaktionsschnell bleibt, ohne dass komplexe, separate Asset-Pakete erforderlich sind.
Grundlegendes zum Arbeitsspeicher in Android
Um effektive Strategien für die Speicherbudgetierung zu entwickeln, müssen Entwickler verstehen, wie die Android-Plattform den physischen Speicher verwaltet und wie sie den aktiven Speicherbedarf deines Spiels misst.
Wichtige Konzepte zum Android-Arbeitsspeicher
Grundlegende Konzepte zur Speicherverwaltung auf Plattformebene finden Sie in der offiziellen Übersicht über die Speicherverwaltung. Diese Ressource deckt vier Architekturbereiche ab:
- Arbeitsspeicher – Übersicht: Android verwendet Paging und Memory-Mapping (mmap) zur Verwaltung des Arbeitsspeichers. Es unterstützt keine herkömmliche Auslagerungsdatei auf dem Laufwerk, sondern nutzt die Seitenkomprimierung (mit zRAM) und die Seitenrückgewinnung, um physischen Arbeitsspeicher freizugeben.
- Arbeitsspeicherzuweisung zwischen Prozessen: Android teilt den RAM im gesamten System auf. Es weist bestimmte Heaps für die Ausführung der virtuellen Dalvik- oder ART-Maschine zu und ermöglicht es nativen Entwicklungsumgebungen (z. B. C++-Game-Engines), Speicher vom nativen System-Heap anzufordern.
- Speicherverwaltung für Apps: Android verwendet ein Multiprozessmodell. Daher wird von Anwendungen erwartet, dass sie ihren Lebenszyklusstatus dynamisch überwachen und nicht benötigte Ressourcen (z. B. nicht im Cache gespeicherte Grafiken und Bitmaps) freiwillig freigeben, um die Systemleistung zu unterstützen.
- Übersicht über Prozesse und Threads: Das System kategorisiert Prozesse in eine Hierarchie, die auf ihrer aktuellen Sichtbarkeit und Bedeutung für den Nutzer basiert. So wird festgelegt, welche Prozesse aktiv bleiben und welche bei geringem Arbeitsspeicher zuerst beendet werden.
Der Messwert für den Gesamtspeicherbedarf
Der Android 17-Arbeitsspeicherbegrenzer auf Plattformebene bewertet den Prozessverbrauch anhand des Gesamtspeicherbedarfs und nicht anhand der Gesamtgröße des residenten Arbeitsspeichers (RSS) oder der Größe des virtuellen Arbeitsspeichers.
Gesamter Speicherbedarf = anonyme RSS (RssAnon) + unkomprimierte Auslagerung (VmSwap)
Damit Spiele die Plattformlimits nicht überschreiten, musst du genau wissen, was diese Messwerte auf Systemebene bedeuten. Weitere Informationen zu diesen Messwerten, zur physischen RAM-Zuweisung und zur Verarbeitung von dateigestützten Seiten finden Sie unter RSS- und Swap-Messwerte verstehen im Leitfaden Arbeitsspeichernutzung überwachen.
Arbeitsspeicherbeschränkungen
Um die Systemstabilität aufrechtzuerhalten und zu verhindern, dass Anwendungen zu viele Ressourcen verbrauchen, verwaltet die Android-Plattform Arbeitsspeicherlimits für laufende Prozesse.
Memory Limiter in Android 17 und höher
Unter Android 17 (API-Level 37) und höher werden strenge, App-spezifische Arbeitsspeicherlimits mithilfe von Linux cgroup v2 verwaltet, um zu verhindern, dass einzelne Apps systemweite Instabilität verursachen. Weitere Informationen zur technischen Implementierung finden Sie im AOSP Memory Limiter Guide und im Blogbeitrag Prioritizing Memory Efficiency: Essential Steps for Android 17.
- Mechanismus: Der Memory Limiter überwacht alle Anwendungsprozesse und weist dynamisch Limits basierend auf dem Lebenszyklusstatus des Prozesses zu:
- Sichtbare Prozesse (Vordergrund): App-Prozesse, die derzeit eine Benutzeroberfläche anzeigen, benötigen voraussichtlich einen größeren Arbeitssatz an Ressourcen und erhalten ein großzügigeres Limit.
- Nicht sichtbare Prozesse (Hintergrund oder Dienste): App-Prozesse, die aktiv sind, ohne eine Benutzeroberfläche anzuzeigen, sind auf ein engeres, restriktiveres Budget beschränkt.
- Kernel-Attribute: Der Dienst basiert auf zwei Hauptattributen:
memory.high: Ein weiches Limit. Wenn dieser Wert überschritten wird, drosselt der Kernel den Prozess und versucht, Arbeitsspeicher aggressiv zurückzugewinnen. Diese Rückforderung kann die Leistung des Spiels beeinträchtigen.memory.swap.max: Verwaltet eine feste Obergrenze für den Swap- oder zRAM-Speicherplatz, den der Prozess verwenden kann.
- Beendigungsverhalten: Wenn ein Prozess weiterhin anonymen Speicher über
memory.highhinaus zuweist und seine Auslagerungskapazität erschöpft, schlagen Zuweisungen fehl und das Betriebssystem beendet den Prozess ohne Benachrichtigung. Diese Beendigung wird mitApplicationExitInfounter dem Beendigungsgrund Memory Limiter protokolliert (verfügbar ab Android 17, 26Q4).
Neue Arbeitsspeicherlimits in Play Console Vitals
Damit Entwickler Speicherprobleme proaktiv erkennen können, führt Google Play neue Messwerte in Android Vitals in der Play Console ein. In der Play Console wird das 90. Perzentil (P90) des anonymen RSS- und Auslagerungsspeicherbedarfs Ihrer Spielsitzungen erfasst, um extreme Ausreißer zu identifizieren.
Die Schwellenwerte für Warnungen und Maßnahmen werden anhand der physischen RAM-Kapazität des Geräts und der Prozessstatus skaliert. Diese Limits gelten in zwei verschiedenen Phasen.
Detaillierte Richtlinien und Speicherlimits finden Sie unter Android Vitals – Was sind die Grenzwerte zu unerwünschtem Verhalten?.
Für Nutzer sichtbare Dienste
Wahrnehmbare Dienste sind kritische Hintergrundprozesse, die das Android-System als für den Nutzer wahrnehmbar einstuft. Dieser Status umfasst alle laufenden Prozesse:
- Dienste im Vordergrund
- Express-Jobs
- Vom Nutzer initiierte Datenübertragungsvorgänge
- Systemgebundene Dienste oder Dienste, die an andere Anwendungen gebunden sind
Da wahrnehmbare Dienste für kritische, lang andauernde Aufgaben im Hintergrund konzipiert sind, sind sie sehr anfällig für kumulative Lebenszykluslecks. Bei den Arbeitsspeicherlimits der Android-Plattform wird dieser Status nicht als „Vordergrund“ behandelt. Das bedeutet, dass Ihr Spiel, wenn es im Hintergrund ausgeführt wird, aber weiterhin einen wahrnehmbaren Dienst ausführt, den strengeren Arbeitsspeicherlimits für den Hintergrund oder Dienste unterliegt, die auf der Seite der Google Play-Hilfe aufgeführt sind. Spiele müssen unnötige Assets aggressiv kürzen, wenn sie vom Vordergrund in einen wahrnehmbaren Dienststatus im Hintergrund wechseln.
R8-Anforderungen
Um die Bytecode-Größe zu minimieren und den grundlegenden Java-Prozessaufwand zu reduzieren, wird die Codeoptimierung in der Google Play Console im Rahmen der Qualitätsrichtlinien für Apps bewertet. Weitere Informationen zu den Optimierungsanforderungen und -limits für Spiele finden Sie in der Android Vitals-Dokumentation unter DEX-Codeoptimierung.
Wenn Sie R8 in einem Android-Standardprojekt konfigurieren möchten, folgen Sie der Anleitung unter App-Optimierung aktivieren. Informationen zum Aktivieren der erweiterten Einstellungen für die Verkleinerung und Optimierung finden Sie unter R8 im Vollmodus verwenden. Mit dem R8 Configuration Analyzer können Sie herausfinden, welche Regeln verhindern, dass R8 Klassen verschleiert oder ungenutzten Code entfernt.
Wenn du eine Game-Engine verwendest, variiert das Standardverhalten von R8 je nach Engine und Version:
- Unity: Die Codeminimierung ist standardmäßig deaktiviert. Sie müssen sie in den Projekteinstellungen aktivieren. Weitere Informationen zur Versionsunterstützung und zu den Konfigurationsschritten finden Sie unter Unity-Code mit R8 verkleinern und optimieren.
- Unreal Engine: Ab UE 4.25 ist R8 in Release-Builds standardmäßig aktiviert. Sie müssen daher Keep-Regeln für JNI-Bridges und Plug-ins verwalten. Weitere Informationen zu Versionsdetails und zur UPL-Konfiguration finden Sie unter Unreal Engine-Code mit R8 verkleinern und optimieren.
Bitmap-Anforderungen
Bitmaps machen einen großen Teil der Arbeitsspeichernutzung bei modernen High-Fidelity-Spielen aus. Da Bitmap-Pixeldaten unter Android 8.0 (API-Level 26) und höher direkt im nicht verwalteten nativen Heap gespeichert werden, kann das nicht optimierte Laden von Bildern dazu führen, dass Prozesse die Speichergrenzwerte der Plattform überschreiten. Best Practices zur Bildskalierung und zum Caching finden Sie unter Bildnutzung optimieren.
Arbeitsspeichernutzung überwachen
Wenn du den Arbeitsspeicher deines Spiels effektiv optimieren möchtest, musst du zuerst verstehen, wie die Android-Plattform den Speicherbedarf misst. In Android 17 wird der Arbeitsspeichermesswert aktualisiert, um die Summe aus anonymem RSS (RssAnon) und unkomprimiertem Swap (VmSwap) zu erfassen, wobei dateibasierter oder GPU-privater Arbeitsspeicher ausgeschlossen wird. In diesem Leitfaden wird beschrieben, wie Sie Tools auf Systemebene wie Perfetto und meminfo verwenden, Diagnose-APIs wie ProfilingManager und onTrimMemory implementieren und genaue Arbeitsspeicherzuweisungen in Unity und Unreal Engine extrahieren. Hier erfährst du, wie du dein Spiel genau profilierst und die Leistungsstörungen vermeidest, die mit herkömmlichen Laufzeit-Speicherabfragen verbunden sind.
Weitere Informationen finden Sie unter Arbeitsspeichernutzung überwachen.
Strategien zur Reduzierung des Speicherbedarfs
Game-Engines vereinfachen zwar die plattformübergreifende Entwicklung, aber ihre standardmäßige Speicherverwaltung kann zu Speicherlimits auf Betriebssystemebene führen. Auf dieser Seite werden praktische Optimierungsschritte beschrieben, die speziell auf Unity und Unreal Engine zugeschnitten sind. Hier erfahren Sie, warum die Verwendung von Java-basierten onTrimMemory-Callbacks in Unity zu Deadlocks führen kann und wie Sie stattdessen native Lebenszyklus-Callbacks verwenden. Außerdem lernen Sie wichtige Optimierungen auf Asset-Ebene kennen, z. B. die Verwendung der ASTC-8x8-Texturkomprimierung und die Konfiguration von Asset-Entladungen, damit Ihr Spiel auf allen Hardwarestufen reibungslos läuft.
Weitere Informationen finden Sie unter Arbeitsspeichernutzung reduzieren.