Arbeitsspeicher in Spielen effektiv 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 es es verlangsamt oder vollständig beendet. Weitere Informationen zu diesen Optimierungen finden Sie unter Arbeitsspeicherzuweisung zwischen Prozessen.

Auf dieser Seite erfahren Sie, wie Sie vermeiden, dass sich der Arbeitsspeicher auf Ihr Spiel auswirkt.

Auf onTrimMemory() antworten

Das System verwendet onTrimMemory(), um Ihre App darüber zu informieren, dass nur noch wenig Arbeitsspeicher zur Verfügung steht und die App möglicherweise beendet wird. Viele Male ist dies die einzige Warnung, die deine App erhält. Dieser Callback hat im Verhältnis zum Low Memory Killer (LMK) eine hohe Latenz. Daher ist es wichtig, schnell auf den Callback zu reagieren.

Reduzieren Sie als Reaktion auf diesen Callback die Geschwindigkeit, Anzahl und Größe der Zuweisungen. onTrimMemory() übergibt eine Konstante, die den Schweregrad angibt. Sie sollten jedoch auf die erste Warnung reagieren, da eine Zuweisung schneller möglich ist, als onTrimMemory() reagieren kann.

Kotlin

class MainActivity : AppCompatActivity(), ComponentCallbacks2 {
    override fun onTrimMemory(level: Int) {
        when (level) {
            ComponentCallbacks2.TRIM_MEMORY_MODERATE,
                ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW,
                ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL -> // Respond to low memory condition
            else -> Unit
        }
    }
}

Java

public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 {
    public void onTrimMemory(int level) {
        switch (level) {
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
              // Respond to low memory condition
                break;
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
              // Respond to low memory condition
                break;
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
              // Respond to low memory condition
                break;
            default:
                break;

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 bietet eine viel höhere Trefferquote und Präzision bei der Vorhersage bevorstehender LMKs. Dazu schätzt die API die Menge der verwendeten Speicherressourcen und benachrichtigt die Anwendung, wenn bestimmte Schwellenwerte überschritten werden. Die API kann den geschätzten Prozentsatz des Arbeitsspeicherverbrauchs auch direkt an Ihre App melden. Sie können die Memory Advice API als Alternative zu onTrimMemory-Ereignissen für die Speicherverwaltung verwenden.

Informationen zur Verwendung der Memory Advice API finden Sie im Startleitfaden.

Vorsicht bei Speicherbudgets

Legen Sie das Budget für den Arbeitsspeicher konservativ fest, um nicht genügend Arbeitsspeicher zu erhalten. Hier einige Punkte, die Sie berücksichtigen sollten:

  • Größe des physischen RAM: Spiele verwenden oft zwischen 1⁄4 und 1⁄2 des physischen RAM-Speichers auf dem Gerät.
  • Maximale zRAM-Größe: Je mehr zRAM vorhanden ist, desto mehr Arbeitsspeicher hat das Spiel zuzuweisen. Dieser Wert kann je nach Gerät variieren. Suchen Sie in /proc/meminfo nach SwapTotal, um diesen Wert zu finden.
  • Arbeitsspeichernutzung des Betriebssystems: Geräte, die Systemprozessen mehr RAM zur Verfügung stellen, lassen weniger Arbeitsspeicher für das Spiel zur Verfügung. Das System beendet den Spielprozess, bevor Systemprozesse beendet werden.
  • Arbeitsspeichernutzung installierter Apps: Teste dein Spiel auf Geräten, auf denen viele Apps installiert sind. Social-Media- und Chat-Anwendungen müssen ständig ausgeführt werden und haben einen Einfluss auf den kostenlosen Speicher.

Wenn Sie kein konservatives Arbeitsspeicherbudget festlegen können, sollten Sie einen flexibleren Ansatz verfolgen. Wenn im System nur noch wenig Arbeitsspeicher auftritt, reduzieren Sie den vom Spiel belegten Arbeitsspeicher. Weisen Sie beispielsweise Texturen mit geringerer Auflösung zu oder speichern Sie weniger Shader als Reaktion auf onTrimMemory(). Dieser dynamische Ansatz der Speicherzuweisung erfordert mehr Arbeit des Entwicklers, insbesondere in der Entwicklungsphase des Spiels.

Seitensperren vermeiden

Ein Schaden tritt auf, wenn nur noch wenig kostenloser Speicher verfügbar ist, dieser aber nicht ausreicht, um das Spiel zu beenden. In diesem Fall hat kswapd Seiten freigegeben, die das Spiel noch benötigt, und versucht, die Seiten aus dem Arbeitsspeicher neu zu laden. Da nicht genug Platz ist, werden die Seiten ständig ausgetauscht. Das System-Tracing meldet diese Situation als Thread, in dem kswapd kontinuierlich ausgeführt wird.

Ein Symptom für Seitengedrohung sind lange Frame-Times, möglicherweise eine Sekunde oder mehr. Reduzieren Sie den Arbeitsspeicherbedarf des Spiels, um dieses Problem zu beheben.

Verfügbare Tools verwenden

Android verfügt über eine Reihe von Tools, die helfen zu verstehen, wie das System den Arbeitsspeicher verwaltet.

Speicherinformationen

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

Sie haben folgende Möglichkeiten, die meminfo-Statistiken auszugeben:

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

Die Statistik PrivateDirty zeigt die RAM-Größe im Prozess an, die nicht auf das Laufwerk übertragen werden kann und nicht mit anderen Prozessen geteilt wird. Der Großteil dieser Menge steht dem System zur Verfügung, wenn der Prozess beendet wird.

Arbeitsspeicher-Tracepoints

Arbeitsspeicher-Tracepoints erfassen die Menge des RSS-Arbeitsspeichers, der vom Spiel genutzt wird. Die Berechnung der RSS-Arbeitsspeichernutzung erfolgt viel schneller als die Berechnung der PST-Nutzung. Da RSS schneller berechnet werden kann, zeigt RSS bei Änderungen der Arbeitsspeichergröße eine präzisere Messung der Spitzenauslastung an. Daher ist es einfacher, Spitzen zu erkennen, die dazu führen können, dass dem Spiel der Arbeitsspeicher ausgeht.

Perfetto und lange Traces

Perfetto ist eine Suite von Tools, mit denen Leistungs- und Speicherinformationen auf einem Gerät erfasst und in einer webbasierten UI dargestellt werden können. Es unterstützt beliebig lange Traces, sodass Sie sehen können, wie sich RSS im Laufe der Zeit verändert. Sie können auch SQL-Abfragen für die Daten absetzen, die sie für die Offline-Verarbeitung erzeugt. Aktivieren Sie lange Traces in der System Tracing-Anwendung. Achten Sie darauf, dass die Kategorie memory:Memory für den Trace aktiviert ist.

Heapprofd

heapprofd ist ein Tool zum Erfassen des Arbeitsspeichers, das zu Perfetto gehört. Dieses Tool kann Ihnen helfen, Speicherlecks zu finden. Es zeigt an, wo Arbeitsspeicher mit malloc zugewiesen wurde. heapprofd kann mit einem Python-Skript gestartet werden. Da das Tool einen geringen Aufwand hat, beeinträchtigt es die Leistung nicht wie andere Tools wie Malloc Debug.

Fehlerbericht

bugreport ist ein Logging-Tool, mit dem Sie herausfinden können, ob Ihr Spiel abgestürzt ist, weil nicht genügend Arbeitsspeicher vorhanden ist. Die Ausgabe des Tools ist viel detaillierter als die Verwendung von Logcat. Diese Methode ist nützlich für das Debugging des Arbeitsspeichers, da sie anzeigt, ob Ihr Spiel abgestürzt ist, weil nicht genügend Arbeitsspeicher vorhanden ist, oder ob es vom LMK abgebrochen wurde.

Weitere Informationen finden Sie unter Fehlerberichte erfassen und lesen.