Speicherplatz in Spielen effizient verwalten

Auf der Android-Plattform versucht das System, so viel Systemspeicher (RAM) wie möglich zu verwenden, und führt verschiedene Speicheroptimierungen durch, um bei Bedarf Speicherplatz freizugeben. Diese Optimierungen können sich negativ auf Ihr Spiel auswirken, indem sie es verlangsamen oder ganz beenden. Weitere Informationen zu diesen Optimierungen finden Sie im Thema Arbeitsspeicherzuweisung an Prozesse.

Auf dieser Seite wird beschrieben, wie Sie verhindern können, dass Ihr Spiel von Problemen mit zu wenig Arbeitsspeicher betroffen ist.

Auf onTrimMemory() reagieren

Das System verwendet onTrimMemory() , um Ihre App über Lebenszyklusereignisse zu informieren, die eine gute Gelegenheit für Ihre App darstellen, die Arbeitsspeichernutzung freiwillig zu reduzieren und zu vermeiden, dass sie vom Low-Memory-Killer (LMK) beendet wird, um Arbeitsspeicher für andere Apps freizugeben.

Wenn Ihre App im Hintergrund beendet wird, wird der Nutzer beim nächsten Start Ihrer App einen langsamen Kaltstart erleben. Bei Apps, die ihre Arbeitsspeichernutzung reduzieren, wenn sie in den Hintergrund wechseln, ist es weniger wahrscheinlich, dass sie im Hintergrund beendet werden.

Wenn Sie auf Trim-Ereignisse reagieren, sollten Sie große Arbeitsspeicherzuweisungen freigeben, die nicht sofort benötigt werden und bei Bedarf neu erstellt werden können. Wenn Ihre App beispielsweise einen Cache mit Bitmaps enthält, die aus lokal gespeicherten komprimierten Bildern decodiert wurden, ist es oft eine gute Idee, diesen Cache als Reaktion auf TRIM_MEMORY_UI_HIDDEN zu verkleinern oder zu leeren.

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.
            }
        }
    }
}

Arbeitsspeicherbudgets konservativ festlegen

Legen Sie das Arbeitsspeicherbudget konservativ fest, um zu vermeiden, dass der Arbeitsspeicher ausgeht. Einige Punkte, die Sie berücksichtigen sollten:

  • Größe des physischen RAM: Spiele verwenden oft zwischen ¼ und ½ des physischen RAM auf dem Gerät.
  • Maximale zRAM-Größe: Mehr zRAM bedeutet, dass dem Spiel potenziell mehr Arbeitsspeicher zugewiesen werden kann. Dieser Wert kann je nach Gerät variieren. Suchen Sie in /proc/meminfo nach SwapTotal, um diesen Wert zu finden.
  • Arbeitsspeichernutzung des Betriebssystems: Bei Geräten, die mehr RAM für System prozesse reservieren, bleibt weniger Arbeitsspeicher für Ihr Spiel übrig. Das System beendet den Prozess Ihres Spiels, bevor es Systemprozesse beendet.
  • Arbeitsspeichernutzung 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 wirken sich auf die Menge des kostenlosen Arbeitsspeichers aus.

Wenn Sie kein konservatives Arbeitsspeicherbudget festlegen können, wählen Sie einen flexibleren Ansatz. Wenn das System Probleme mit zu wenig Arbeitsspeicher hat, reduzieren Sie die Menge an Arbeitsspeicher, die vom Spiel verwendet wird. Weisen Sie beispielsweise als Reaktion auf onTrimMemory() Texturen mit niedrigerer Auflösung zu oder speichern Sie weniger Shader. Dieser dynamische Ansatz für die Arbeitsspeicherzuweisung erfordert mehr Arbeit vom Entwickler, insbesondere in der Game-Design-Phase.

Seitenflattern vermeiden

Seitenflattern tritt auf, wenn der kostenlose Arbeitsspeicher niedrig ist, aber nicht so niedrig, dass das Spiel beendet wird. In dieser Situation hat kswapd Seiten freigegeben, 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 immer wieder ausgelagert werden (kontinuierliches Auslagern). In der Systemtrace wird diese Situation als Thread gemeldet, in dem kswapd kontinuierlich ausgeführt wird.

Ein Symptom von Seitenflattern sind lange Frame-Zeiten, möglicherweise eine Sekunde oder mehr. Reduzieren Sie den Speicherbedarf 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

Dieses Tool erfasst Arbeitsspeicherstatistiken, um zu zeigen, wie viel PSS-Arbeitsspeicher zugewiesen wurde und für welche Kategorien er verwendet wurde.

So geben Sie die Meminfo-Statistiken auf eine der folgenden Arten aus:

  • Verwenden Sie den Befehl adb shell dumpsys meminfo package-name.
  • Verwenden Sie den MemoryInfo Aufruf aus der Android Debug API.

Die PrivateDirty Statistik zeigt die Menge an RAM im Prozess, die nicht auf die Festplatte ausgelagert werden kann und nicht für andere Prozesse freigegeben ist. Der Großteil dieser Menge wird dem System zur Verfügung gestellt, wenn dieser Prozess beendet wird.

Arbeitsspeicher-Tracepoints

Arbeitsspeicher-Tracepoints verfolgen die Menge an RSS-Arbeitsspeicher , die von Ihrem Spiel verwendet wird. Die Berechnung der RSS-Arbeitsspeichernutzung ist viel schneller als die Berechnung der PSS-Nutzung. Da die Berechnung schneller ist, zeigt RSS eine feinere Granularität bei Änderungen der Arbeitsspeichergröße, um die maximale Arbeitsspeichernutzung genauer zu messen. Daher ist es einfacher, Spitzen zu erkennen, die dazu führen könnten, dass dem Spiel der Arbeitsspeicher ausgeht.

Perfetto und lange Traces

Perfetto ist eine Suite von Tools zum Erfassen von Leistungs- und Arbeitsspeicherinformationen auf einem Gerät und zum Anzeigen in einer webbasierten UI. Es unterstützt beliebig lange Traces, sodass Sie sehen können, wie sich RSS im Laufe der Zeit ändert. Sie können auch SQL-Abfragen für die erzeugten Daten ausführen, um sie offline zu verarbeiten. Aktivieren Sie lange Traces in der Systemtrace-App. Achten Sie darauf, dass die memory:Memory Kategorie für die Trace aktiviert ist. Für benutzerdefinierte Arbeitsspeicherinstrumentierung in der Entwicklung und beim Testen können Sie auch die (Beta)heapprofd API verwenden.

heapprofd

heapprofd ist ein Tool zur Arbeitsspeicherverfolgung, das Teil von Perfetto ist. Mit diesem Tool können Sie Arbeitsspeicherlecks finden, indem Sie sehen, wo Arbeitsspeicher mit malloc zugewiesen wurde. heapprofd kann mit einem Python-Skript 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 aufgrund von zu wenig Arbeitsspeicher abgestürzt ist. Die Ausgabe des Tools ist viel detaillierter als bei der Verwendung von logcat. Es ist nützlich für das Debugging von Arbeitsspeicherproblemen, da es zeigt, ob Ihr Spiel aufgrund von zu wenig Arbeitsspeicher abgestürzt ist oder vom LMK beendet wurde.

Weitere Informationen finden Sie unter Fehlerberichte erfassen und lesen.