Im Android-System ist der Grenzwert für die Arbeitsspeicherbegrenzung für Memory Limiter (Android 17+) und der Benchmark-Wert für den Arbeitsspeicher-Vitalwert in der Google Play Console ist 'anonyme RSS + Auslagerung'. Dieser Wert gibt den Grad der physischen Arbeitsspeicherbelastung an, die tatsächlich vom Prozess belegt wird. Er ist ein wichtiger Messwert, der für einen stabilen App-Betrieb überwacht werden muss.
Derzeit ist es schwierig, die Arbeitsspeichernutzung zu messen, die genau mit „anonyme RSS + Auslagerung“ übereinstimmt, entweder zur Laufzeit oder statisch in der Unity Engine.
Auf dieser Seite wird beschrieben, wie Sie den Wert „anonyme RSS + Auslagerung“ mit hoher Zuverlässigkeit durch eine Näherung mithilfe des Unity Profilers, der ProfileRecorder API und des Unity Speicher-Profilers in einer Unity Engine Umgebung verfolgen können.
Arbeitsspeichernutzung zur Laufzeit prüfen
In Unity kann es schwierig sein, die genaue Arbeitsspeichernutzung von Android für 'anonyme RSS + Auslagerung' zur Laufzeit ohne Overhead zu messen. Sie können diesen Wert jedoch mithilfe der integrierten Profiler-APIs von Unity genau schätzen (mit einer Abweichung von etwa 10 %).
Methode 1: Profiler verwenden
Sie können die Gesamtarbeitsspeichernutzung schätzen, indem Sie die von den folgenden Profiler-APIs zurückgegebenen Werte addieren:
using UnityEngine;
using UnityEngine.Profiling;
public class MemoryMonitor : MonoBehaviour
{
public long GetEstimatedMemoryUsageBytes()
{
long totalReserved = Profiler.GetTotalReservedMemoryLong();
long monoHeapSize = Profiler.GetMonoHeapSizeLong();
return totalReserved + monoHeapSize;
}
}
Methode 2: Klasse ProfilerRecorder verwenden
Sie können die Messwerte Total Reserved Memory und Gfx Reserved Memory mit ProfilerRecorder verfolgen:
In Entwicklungs-Builds: Berechnen Sie 'Total Reserved Memory' - 'Gfx Reserved Memory'.
In Release-Builds: Verwenden Sie direkt 'Total Reserved Memory'.
using Unity.Profiling;
using UnityEngine;
public class MemoryMonitor : MonoBehaviour
{
ProfilerRecorder totalRecorder;
#if DEVELOPMENT_BUILD
ProfilerRecorder gfxRecorder;
#endif
private void OnEnable()
{
totalRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Total Reserved Memory");
#if DEVELOPMENT_BUILD
gfxRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Gfx Reserved Memory");
#endif
}
private void OnDisable()
{
totalRecorder.Dispose();
#if DEVELOPMENT_BUILD
gfxRecorder.Dispose();
#endif
}
public long GetEstimatedMemoryUsageBytes()
{
#if DEVELOPMENT_BUILD
if (totalRecorder.Valid && gfxRecorder.Valid)
{
return totalRecorder.LastValue - gfxRecorder.LastValue;
}
#else
if (totalRecorder.Valid)
{
return totalRecorder.LastValue;
}
#endif
return 0;
}
}
Einschränkung:
Arbeitsspeicherzuweisungen, die den Memory Manager von Unity umgehen (z.B. NativeMalloc(IntPtr size)), können von diesen APIs nicht verfolgt werden.
Diese APIs werden je nach Unity-Version möglicherweise nicht unterstützt.
Arbeitsspeicheraufschlüsselung analysieren (statische Analyse)
Wenn zur Laufzeit eine hohe Arbeitsspeichernutzung festgestellt wird, müssen Sie ermitteln, wo Arbeitsspeicher verbraucht wird. Durch die Analyse der Arbeitsspeicherverteilung können Sie unnötige Zuweisungen vermeiden und den gesamten Speicherbedarf des Spiels reduzieren.
Unity Memory Profiler
Für eine detaillierte Speicheranalyse und zur Optimierung Ihres Spiels verwenden Sie das Paket Unity Speicher-Profiler. So finden Sie die Elemente, die der Nutzung von 'anonyme RSS + Auslagerung' des Android-Betriebssystems entsprechen:
- Erstellen Sie mit dem Unity Speicher-Profiler einen Snapshot.
- Öffnen Sie den Snapshot und rufen Sie All of Memory > Resident Memory on Device auf.
Berechnen Sie die Summe der folgenden Elemente:
- Untracked
- Android Runtime
- Nativ
- Verwaltet
Abbildung 1. Arbeitsspeicherbeschreibungen werden im residenten Arbeitsspeicher gespeichert.
Die Gesamtsumme dient als praktischer Ersatz für 'anonyme RSS + Auslagerung' des Android-Betriebssystems und liefert umsetzbare Erkenntnisse für die Arbeitsspeicheranalyse von Spielen.
Einschränkung:
Bei hoher Arbeitsspeicherbelastung komprimiert oder lagert das Android-Betriebssystem möglicherweise aktive Arbeitsspeicherseiten aus, um Arbeitsspeicher freizugeben. Da der Unity Speicher-Profiler ausgelagerten Arbeitsspeicher nicht verfolgen kann, können bei hoher Arbeitsspeichernutzung Abweichungen auftreten.
Diese Funktionen sind je nach Unity-Version möglicherweise eingeschränkt.
Beispielskripte in C#
In den Skripts AndroidAndroidProcessStats.cs und
GameMemoryMonitor.cs finden Sie Beispiele dafür, wie Sie den Status und
den Arbeitsspeicherbedarf der Prozesse Ihres Spiels zur Laufzeit überwachen können.
- Das Skript
AndroidProcessStatszeigt, wie Sie JNI (Java Native Interface) verwenden, um eine Verknüpfung zu denActivityManager-APIs von Android herzustellen. Es bietet Funktionen zum Abrufen von laufenden Prozessen, ihrer Wichtigkeit und des Betriebssystemstatus. Außerdem enthält es einfache Methoden zum Lesen von Arbeitsspeicherstatistiken direkt aus dem Linux-Dateisystem/proc. - Das Skript
GameMemoryMonitorzeigt, wie Sie diese Informationen für die kontinuierliche Überwachung und das Debugging verwenden. Dazu gehört auch, wie Sie die Android-APIs in einem Hintergrundthread abfragen, um Leistungseinbußen zu vermeiden (da die Verwendung von JNI und das Abfragen von Arbeitsspeicherinformationen kostspielig sein kann), und wie Sie Lebenszyklusereignisse wieOnApplicationPausenutzen, um Arbeitsspeicheränderungen zu verfolgen, wenn die App in den Hintergrund verschoben oder fortgesetzt wird.
Wenn Sie diese Tools verwenden möchten, fügen Sie beide Skripts Ihrem Ordner „Assets“ hinzu und hängen Sie das Skript GameMemoryMonitor an ein GameObject in Ihrer Szene an.
Genauere Bewertung
Wenn Sie die genauen Werte für 'anonyme RSS + Auslagerung' des Android-Betriebssystems überprüfen möchten, verwenden Sie Perfetto. Damit können Sie die genaue Arbeitsspeichernutzung auf Systemebene messen und den Speicherbedarf Ihres Spiels gründlich analysieren.