Auf der Android-Plattform versucht das System, so viel Systemspeicher (RAM) wie möglich zu nutzen, und führt verschiedene Speicheroptimierungen durch, um bei Bedarf Speicherplatz freizugeben. Diese Optimierungen können sich negativ auf Ihr Spiel auswirken, indem es entweder verlangsamt oder vollständig beendet wird. Weitere Informationen zu diesen Optimierungen finden Sie unter Speicherzuweisung zwischen Prozessen.
Auf dieser Seite wird beschrieben, wie Sie verhindern können, dass ein niedriger Arbeitsspeicher Ihr Spiel beeinträchtigt.
Auf onTrimMemory() reagieren
Das System verwendet onTrimMemory()
, um Ihre App über Lebenszyklusereignisse zu informieren, bei denen sie ihre Arbeitsspeichernutzung freiwillig reduzieren und verhindern kann, dass sie vom Low-Memory-Killer (LMK) beendet wird, um Arbeitsspeicher für andere Apps freizugeben.
Wenn Ihre App im Hintergrund beendet wird, dauert es beim nächsten Starten der App länger, bis sie vollständig gestartet ist. Apps, die ihre Arbeitsspeichernutzung reduzieren, wenn sie in den Hintergrund wechseln, werden im Hintergrund seltener beendet.
Wenn Sie auf Trim-Ereignisse reagieren, sollten Sie große Speicherzuweisungen freigeben, die nicht sofort benötigt werden und bei Bedarf neu erstellt werden können. Wenn Ihre App beispielsweise einen Cache mit Bitmaps hat, die aus lokal gespeicherten komprimierten Bildern decodiert wurden, ist es oft sinnvoll, diesen Cache als Reaktion auf TRIM_MEMORY_UI_HIDDEN
zu kürzen oder zu löschen.
Kotlin
class MainActivity : AppCompatActivity(), ComponentCallbacks2 { override fun onTrimMemory(level: Int) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } }
Java
public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 { public void onTrimMemory(int level) { switch (level) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } } }
C#
using UnityEngine; using System.Collections; using System.Collections.Generic; class LowMemoryTrigger : MonoBehaviour { private void Start() { Application.lowMemory += OnLowMemory; } private void OnLowMemory() { // Respond to low memory condition (e.g., Resources.UnloadUnusedAssets()) } }
Memory Advice API Beta verwenden
Die Memory Advice API wurde als Alternative zu onTrimMemory entwickelt. Sie hat eine viel höhere Trefferquote und Genauigkeit bei der Vorhersage bevorstehender LMKs. Dazu schätzt die API die Menge der verwendeten Arbeitsspeicherressourcen und benachrichtigt die App, wenn bestimmte Grenzwerte überschritten werden. Die API kann auch den geschätzten Prozentsatz der Speichernutzung direkt an Ihre App melden. Sie können die Memory Advice API als Alternative zu onTrimMemory
-Ereignissen zur Speicherverwaltung verwenden.
Eine Anleitung zur Verwendung der Memory Advice API finden Sie im Einstiegsleitfaden.
Seien Sie bei Arbeitsspeicherbudgets zurückhaltend
Planen Sie den Arbeitsspeicher konservativ, um zu vermeiden, dass er aufgebraucht wird. Berücksichtigen Sie dabei Folgendes:
- Größe des physischen RAM: Spiele verbrauchen oft zwischen einem Viertel und der Hälfte des physischen RAM-Speicherplatzes auf dem Gerät.
- Maximale zRAM-Größe: Je mehr zRAM, desto mehr Arbeitsspeicher kann dem Spiel zugewiesen werden. Dieser Wert kann je nach Gerät variieren. Sie finden ihn in
/proc/meminfo
unterSwapTotal
. - Arbeitsspeichernutzung des Betriebssystems: Geräte, die Systemprozessen mehr RAM zuweisen, haben weniger Arbeitsspeicher für Ihr Spiel übrig. Das System beendet den Prozess Ihres Spiels, bevor es Systemprozesse beendet.
- Speichernutzung installierter Apps: Testen Sie Ihr Spiel auf Geräten, auf denen viele Apps installiert sind. Social-Media- und Chat-Apps müssen ständig ausgeführt werden und beeinträchtigen den kostenlosen Arbeitsspeicher.
Wenn Sie sich nicht auf ein konservatives Arbeitsspeicherbudget festlegen können, sollten Sie einen flexibleren Ansatz wählen. Wenn das System Probleme mit wenig Arbeitsspeicher hat, reduzieren Sie die Arbeitsspeichermenge, die das Spiel belegt. Beispielsweise können Sie Texturen mit niedrigerer Auflösung zuweisen oder weniger Shader als Reaktion auf onTrimMemory()
speichern. Dieser dynamische Ansatz für die Speicherzuweisung erfordert mehr Arbeit von den Entwicklern, insbesondere in der Phase des Game-Designs.
Seitenflattern vermeiden
Thrashing tritt auf, wenn der kostenlose Arbeitsspeicher zwar niedrig ist, aber nicht so niedrig, dass das Spiel beendet wird.
In diesem Fall hat kswapd
Seiten wiederhergestellt, die das Spiel noch benötigt. Daher versucht es, die Seiten aus dem Arbeitsspeicher neu zu laden. Es ist nicht genügend Speicherplatz vorhanden, sodass die Seiten ständig ausgetauscht werden (kontinuierliches Auslagern).
Beim System-Tracing wird diese Situation als Thread angezeigt, in dem kswapd
kontinuierlich ausgeführt wird.
Ein Symptom für einen Datenüberlauf sind lange Frame-Zeiten, möglicherweise eine Sekunde oder mehr. Reduziere den Arbeitsspeicherbedarf des Spiels, um dieses Problem zu beheben.
Verfügbare Tools verwenden
Android bietet eine Reihe von Tools, mit denen Sie nachvollziehen können, wie das System den Arbeitsspeicher verwaltet.
Meminfo
Mit diesem Tool werden Arbeitsspeicherstatistiken erfasst, um zu sehen, wie viel PSS-Speicher zugewiesen wurde und für welche Kategorien er verwendet wurde.
Sie haben folgende Möglichkeiten, die Statistiken von meminfo zu drucken:
- Führen Sie den Befehl
adb shell dumpsys meminfo package-name
aus. - Verwenden Sie den
MemoryInfo
-Aufruf aus der Android Debug API.
Die Statistik PrivateDirty
gibt den RAM-Speicherplatz im Prozess an, der nicht auf das Laufwerk ausgelagert werden kann und nicht mit anderen Prozessen geteilt wird. Der Großteil dieser Menge wird dem System wieder zur Verfügung gestellt, wenn der Prozess beendet wird.
Speicher-Tracepoints
Speicher-Tracepoints erfassen die Menge an RSS-Speicher, die Ihr Spiel verwendet. Die Berechnung der RSS-Speichernutzung ist viel schneller als die Berechnung der PSS-Nutzung. Da die Berechnung schneller ist, zeigt RSS genauere Details zu Änderungen der Speichergröße für genauere Messungen der Spitzenspeichernutzung. So lassen sich Spitzen leichter erkennen, die dazu führen können, dass dem Spiel der Arbeitsspeicher ausgeht.
Perfetto und lange Traces
Perfetto ist eine Suite von Tools zum Erfassen von Leistungs- und Speicherinformationen auf einem Gerät und zum Darstellen in einer webbasierten Benutzeroberfläche. Es werden beliebig lange Traces unterstützt, sodass Sie sehen können, wie sich RSS im Laufe der Zeit ändert. Sie können auch SQL-Abfragen für die Offlineverarbeitung der generierten Daten ausführen. Aktivieren Sie lange Protokolle über die System-Tracing-App. Achten Sie darauf, dass die Kategorie memory:Memory für das Protokoll aktiviert ist.
heapprofd
heapprofd
ist ein Speicher-Tracking-Tool, das zu Perfetto gehört. Dieses Tool kann Ihnen helfen, Speicherlecks zu finden, indem es anzeigt, wo Speicher mit malloc
zugewiesen wurde. heapprofd
kann mit einem Python-Script gestartet werden. Da das Tool einen geringen Overhead hat, wirkt es sich nicht so stark auf die Leistung aus wie andere Tools wie Malloc Debug.
bugreport
bugreport
ist ein Logging-Tool, mit dem Sie herausfinden können, ob Ihr Spiel abgestürzt ist, weil der Arbeitsspeicher aufgebraucht war. Die Ausgabe des Tools ist viel detaillierter als bei der Verwendung von logcat. Sie ist nützlich für die Speicherfehlerbehebung, da sie angibt, ob Ihr Spiel abgestürzt ist, weil der Arbeitsspeicher aufgebraucht war, oder ob es vom LMK beendet wurde.
Weitere Informationen finden Sie unter Fehlerberichte erfassen und lesen.