
Profilieren und Analysieren der Speichernutzung mit den Speicherprofilierungstools von Unity

-
Indem Sie die Leistung Ihres Spiels für eine breite Palette von Plattformen und Geräten profilieren und optimieren, können Sie Ihre Spielerbasis erweitern und Ihre Erfolgschancen erhöhen.
-
Die Informationen hier sind aus dem Ultimate guide to profiling Unity games (Ausgabe Unity 6) entnommen, einem E-Book, das sowohl von externen als auch von internen Unity Experten für Spieleentwicklung, Profilerstellung und Optimierung erstellt wurde.
Was ist Memory-Profiling?
Memory-Profiling ist weitgehend unabhängig von der Laufzeitleistung, eignet sich aber zum Testen von Hardware-Plattform-Speicherbeschränkungen oder bei Spielabstürzen. Das kann auch relevant sein, wenn Sie die CPU/GPU-Leistung verbessern möchten, indem Sie Änderungen vornehmen, die die Speichernutzung tatsächlich erhöhen.
Es gibt zwei Möglichkeiten, die Speichernutzung Ihrer Anwendung in Unity zu analysieren:
- Das Modul Memory-Profiler: Dies ist ein integriertes Profiler-Modul, das Ihnen grundlegende Informationen darüber gibt, wo Ihre Anwendung den Speicher im regulären Profiler verwendet.
- Der Memory-Profiler: Dies ist ein dediziertes Tool, das Sie als Unity Paket zu Ihrem Projekt hinzufügen können. Es fügt dem Unity Editor ein zusätzliches Memory Profiler-Fenster hinzu, mit dem Sie die Speichernutzung in Ihrer Anwendung noch detaillierter analysieren können. Sie können Snapshots speichern und vergleichen, um Speicherlecks zu finden. Oder Sie sehen sich das Speicherlayout an, um Fragmentierungsprobleme zu erkennen. Wir werden dies später in diesem Leitfaden im Detail behandeln und uns hier auf die allgemeinen Überlegungen konzentrieren, die Sie berücksichtigen müssen.
Beide Tools ermöglichen es Ihnen, die Speichernutzung zu überwachen, Bereiche einer Anwendung zu finden, in denen die Speichernutzung höher ist als erwartet, und die Speicherfragmentierung zu finden und zu verbessern.

Verstehen und Festlegen eines Speicherbudgets
Das Verständnis und die Budgetierung für die Speichergrenzen Ihrer Zielgeräte sind für die Multiplattform-Entwicklung von entscheidender Bedeutung. Bei der Gestaltung von Szenen und Leveln müssen Sie sich an das Speicherbudget halten, das für jedes Zielgerät festgelegt ist. Durch die Festlegung von Grenzen und Richtlinien können Sie sicherstellen, dass Ihre Anwendung innerhalb der Grenzen der Hardwarespezifikationen der einzelnen Plattformen gut funktioniert.
Gerätespeicherspezifikationen finden Sie in der Entwicklerdokumentation.
Es kann auch nützlich sein, Inhaltsbudgets nach Mesh- und Shader-Komplexität sowie Texturkompression festzulegen. Diese alle spielen eine Rolle, wie viel Speicher zugewiesen ist. Diese Budgetzahlen können während des Entwicklungszyklus des Projekts herangezogen werden.
Physische RAM-Limits bestimmen
Da jede Plattform über ein Speicherlimit verfügt, benötigt Ihre Anwendung ein Speicherbudget für jedes ihrer Zielgeräte. Verwenden Sie den Memory-Profiler, um einen aufgenommenen Schnappschuss Ihrer Speichernutzung anzusehen. Der Hardwareressourcen-Schnappschuss (siehe Bild unten) zeigt die Größen von physischem Random Access Memory (RAM) und Video Random Access Memory (VRAM). Diese Zahl berücksichtigt nicht die Tatsache, dass möglicherweise nicht der gesamte Speicherplatz genutzt werden kann. Es bietet jedoch eine nützliche Ballpark-Figur für den Einstieg in die Arbeit.
Es empfiehlt sich, Hardwarespezifikationen für Zielplattformen zu vergleichen, da die hier angezeigten Zahlen möglicherweise nicht immer das ganze Bild zeigen. Die Entwicklerkit-Hardware verfügt manchmal über mehr Speicher, oder Sie arbeiten mit Hardware, die eine einheitliche Speicherarchitektur hat.

Die niedrigste RAM-Spezifikation bestimmen
Identifizieren Sie die Hardware mit der niedrigsten RAM-Spezifikation für jede Plattform, die Sie unterstützen, und verwenden Sie diese als Richtschnur für Ihre Entscheidung über das Speicherbudget. Denken Sie daran, dass möglicherweise nicht der gesamte physische Speicher genutzt werden kann. Beispielsweise könnte auf einer Konsole ein Hypervisor ausgeführt werden, der ältere Spiele unterstützt, die möglicherweise einen Teil des gesamten Speichers verbrauchen. Überlegen Sie sich einen Prozentsatz (z. B. 80 % der Gesamtmenge), den Sie je nach Ihrem spezifischen Szenario als Team verwenden können. Für mobile Plattformen können Sie auch eine Aufteilung in mehrere Stufen von Spezifikationen in Betracht ziehen, um eine bessere Qualität und Funktionen für diejenigen mit High-End-Geräten zu unterstützen.
Betrachten Sie die Budgets pro Team für größere Teams
Sobald Sie ein Speicherbudget definiert haben, können Sie Speicherbudgets für jedes Team festlegen. Ihre Umgebungsgrafiker erhalten beispielsweise eine bestimmte Menge an Speicher für jedes geladene Level oder jede Szene, das Audioteam erhält Speicherzuweisung für Musik- und Toneffekte usw. Auch wenn dies starr erscheinen mag, betrachten Sie es als Richtlinien, um die kreativen Entscheidungen, die getroffen werden, im Vergleich zu den Kosten der Ressourcen zu informieren.
Es ist wichtig, im Laufe des Projekts flexibel mit den Budgets umzugehen. Wenn ein Team unter Budget kommt, weisen Sie den Überschuss einem anderen Team zu, wenn es die Bereiche des Spiels, die es entwickelt, verbessern kann.
Sobald Sie sich für die Speicherbudgets Ihrer Zielplattformen entschieden und diese festgelegt haben, verwenden Sie als nächstes Profiling-Tools, um die Speichernutzung in Ihrem Spiel zu überwachen und zu verfolgen. So können Sie fundierte Entscheidungen treffen und bei Bedarf Maßnahmen ergreifen.
Einige Tipps für Memory-Profiling
Um auf hoher Ebene festzustellen, wann sich die Speichernutzung den Plattformbudgets anzunähern beginnt, verwenden Sie die folgende „Back-of-Serviette“-Berechnung:
System verwendeter Speicher (oder Gesamter reservierter Speicher, wenn System verwendet 0 anzeigt) + Ballparkpuffer von nicht nachverfolgtem Speicher / Gesamter Plattformspeicher
Wenn sich diese Zahl 100 % des Speicherbudgets Ihrer Plattform nähert, können Sie mithilfe des Memory Profiler-Pakets herausfinden, warum.
In Unity 6 werden viele der Funktionen des Memory-Profiler-Moduls durch das Memory-Profiler-Paket ersetzt, aber Sie können das Modul trotzdem verwenden, um Ihre Bemühungen um die Speicheranalyse zu ergänzen. Zum Beispiel:
- GC Zuordnungen zu erkennen: Diese werden zwar im Modul angezeigt, sind aber mit dem Projekt-Auditor oder Deep Profiling einfacher aufzuspüren.
- Schnelle Betrachtung der verwendeten/reservierten Größe des Heaps
- Shader-Speicheranalyse
- Verwenden Sie die Detailansicht im Memory-Profiler-Modul, um in die höchsten Speicherbäume einzusteigen und herauszufinden, was den meisten Speicher verbraucht.
Hier sind einige weitere Ressourcen, die Ihnen helfen, weitere Anwendungsfälle und Funktionen des Unity Profilers zu erkunden:
- Profilerübersicht im Unity Handbuch
– Einführung in Profiling in Unity
Wie man ein Spiel profiliert und optimiert
Normalerweise sollten Sie Ihr Profil mit einem leistungsstarken Entwicklersystem erstellen, das viel Speicherplatz zur Verfügung hat (Platz zum Speichern großer Speicher-Snapshots oder zum schnellen Laden und Speichern dieser Snapshots ist wichtig).
Memory-Profiling ist eine andere Bestie als CPU- und GPU-Profiling, da es selbst zusätzlichen Speicheraufwand verursachen kann. Möglicherweise müssen Sie den Speicher auf High-End-Geräten (mit mehr Speicher) profilieren, aber speziell auf das Speicherbudgetlimit für die niedrigere Zielspezifikation achten.
Einstellungen wie Qualitätsstufen, Grafikstufen und AssetBundle-Varianten können auf leistungsfähigeren Geräten unterschiedliche Speichernutzungen aufweisen. In diesem Sinne sollten Sie einige Details beachten, um das Beste aus dem Speicherprofiling herauszuholen:
- Die Qualität und Grafikeinstellungen können sich auf die Größe von Rendertexturen auswirken, die für Shadow Maps verwendet werden.
- Die Auflösungsskalierung kann sich auf die Größe der Bildschirmpuffer, Rendertexturen und Nachbearbeitungseffekte auswirken.
- Textureinstellungen können die Größe aller Texturen beeinflussen.
- Der maximale LOD kann Modelle und mehr beeinflussen.
Wenn Sie über AssetBundle-Varianten wie eine HD (High Definition)- und eine SD (Standard Definition)-Version verfügen und basierend auf den Spezifikationen Ihres Zielgeräts auswählen, erhalten Sie möglicherweise unterschiedliche Asset-Größen je nachdem, auf welchem Gerät Sie sich profilieren.
- Die Bildschirmauflösung Ihres Zielgeräts beeinflusst die Größe von Rendertexturen, die für Nachbearbeitungseffekte verwendet werden.
- Die unterstützte GrafikAPI eines Geräts kann die Größe von Shadern beeinflussen, je nachdem, welche Varianten davon es unterstützt (oder nicht unterstützt).
- Ein Stufensystem, das unterschiedliche Qualitäts- und Grafikeinstellungen sowie AssetBundle-Varianten verwendet, ist eine großartige Möglichkeit, um auf ein größeres Spektrum von Geräten abzielen zu können.
Sie können beispielsweise eine HD-Version eines Asset-Pakets auf ein 4 GB großes mobiles Gerät und eine SD-Version auf ein 2 GB großes Gerät laden. Beachten Sie jedoch die obigen Variationen in der Speichernutzung und testen Sie unbedingt beide Gerätetypen sowie Geräte mit unterschiedlicher Bildschirmauflösung oder unterstützten Grafik-APIs.
Hinweis: Aufgrund zusätzlicher Objekte, die aus dem Editor und Profiler geladen werden, zeigt der Unity Editor in der Regel immer einen größeren Speicherbedarf. Außerdem ist der Texturspeicherbedarf höher, da sie alle gezwungen sind, im Editor lesen/schreiben zu können.

Das Memory-Profiler-Paket
Das Paket Memory Profiler kann Ihnen helfen, die Speichernutzung Ihres Projekts zu verstehen und zu optimieren. Es ermöglicht Ihnen, „Schnappschüsse“ des Speichers Ihrer Anwendung zu bestimmten Zeitpunkten sowohl im Unity Editor als auch während der Ausführung von Player-Builds auf Ihrem Zielgerät aufzunehmen.
Die Snapshots enthalten eine umfassende Aufschlüsselung der Speichernutzung und zeigen Zuordnungen in der gesamten Engine. Dies hilft Ihnen, Quellen für übermäßige oder unnötige Speichernutzung zu identifizieren, Speicherlecks aufzuspüren und Probleme wie die Heap-Fragmentierung zu inspizieren.
Öffnen Sie nach der Installation des Memory-Profiler-Pakets dieses über Fenster > Analyse > Memory-Profiler.
In der oberen Menüleiste des Memory-Profilers können Sie das Ziel der Spielerauswahl ändern und Schnappschüsse erfassen oder importieren. Über das Dropdown-Menü Zielauswahl in der oberen linken Ecke können Sie den Speicher direkt auf Ihrer Zielhardware profilieren, indem Sie den Memory-Profiler mit dem Remote-Gerät verbinden. Beachten Sie, dass Ihnen die Profilerstellung im Unity Editor aufgrund des vom Editor hinzugefügten Overheads und anderer Tools ungenaue Zahlen liefert.

Snapshots-Komponente
Links im Memory-Profiler-Fenster befindet sich die Schnappschüsse-Komponente. Verwenden Sie dies, um gespeicherte Speicher-Snapshots zu verwalten und zu öffnen oder zu schließen. Die Snapshot-Komponente bietet zwei Ansichten: Single Snapshot und Compare Snapshot.
Ähnlich wie bei der Profilanalyse können Sie mit dem Memory-Profiler zwei Speicher-Snapshots nebeneinander laden und vergleichen. Verwenden Sie diesen Vergleich, um das Speicherwachstum im Zeitverlauf zu verfolgen, die Nutzung zwischen Szenen zu analysieren oder potenzielle Speicherlecks zu identifizieren.
Memory Profiler verfügt über eine Reihe von Registerkarten im Hauptfenster, mit denen Sie sich in Speicher-Schnappschüsse eingraben können, die wichtigsten sind Summary, Unity Objects und All of Memory. Sehen wir uns diese Optionen im Detail an.

Die Registerkarte Zusammenfassung
Die Registerkarte Zusammenfassung bietet Ihnen einen High-Level-Snapshot der Speichernutzung Ihres Projekts zum Zeitpunkt der Aufnahme. Es ist perfekt, wenn Sie einen schnellen und informativen Überblick erhalten möchten, ohne in detaillierte Analysen einzutauchen.
Diese Ansicht hebt wichtige Metriken hervor und kann Ihnen helfen, potenzielle Speicherprobleme oder unerwartete Nutzungsmuster schnell zu erkennen. Das ist besonders nützlich, wenn man Snapshots vergleicht oder die Speichernutzung im Zeitverlauf debuggt. Sehen wir uns einige der wichtigsten Abschnitte an.
Tipps: Im rechten Bereich (siehe Bild unten) finden Sie hilfreiche Kontextinformationen zu Ihrem Schnappschuss. Diese können Sie auf mögliche Probleme hinweisen oder Sie bei der Interpretation der Ergebnisse unterstützen.
Speichernutzung auf dem Gerät: Dies zeigt den Anwendungsfußabdruck im physischen Speicher. Sie umfasst alle Unity und Nicht-Unity Zuweisungen, die sich zum Zeitpunkt der Erfassung im Speicher befinden.
Zugeordnete Speicherverteilung: Diese Ansicht visualisiert, wie zugewiesener Speicher über verschiedene Speicherkategorien verteilt ist.
Beachten Sie die Untracked*-Speicherleiste. Es entspricht dem Speicher, den Unity nicht über sein Speicherverwaltungssystem erfasst. Solche Zuweisungen können von nativen Plugins und Treibern stammen. Verwenden Sie den plattformspezifischen Profiler, um die nicht nachverfolgte Speichernutzung für Ihr Zielgerät zu analysieren.
Verwaltete Heap-Nutzung: In dieser Ansicht finden Sie eine Aufschlüsselung des von der Skripting-VM von Unity verwalteten Speichers, die für verwaltete Objekte verwendeten verwalteten Heap-Speicher, leeren Heap-Speicher, der zuvor von Objekten genutzt wurde oder während der letzten Heap-Erweiterung reserviert wurde, und Speicher, der von einer virtuellen Maschine selbst verwendet wird.
Top-Unity-Objektkategorien: Hier wird angezeigt, welche Arten von Unity Objekten den meisten Speicher im Snapshot belegen (z. B. Texture2D, Mesh, GameObject).

Die Registerkarte Objekte
Auf der Registerkarte Unity Objekte werden alle Unity Objekte angezeigt, denen Speicher zugewiesen ist, wie viel nativen und verwalteten Speicher das Objekt verwendet und die Gesamtanzahl. Verwenden Sie diese Informationen, um Bereiche zu identifizieren, in denen Sie doppelte Speichereinträge beseitigen können, oder um herauszufinden, welche Objekte den meisten Speicher verwenden. Über die Suchleiste finden Sie die Einträge in der Tabelle, die den eingegebenen Text enthalten.
Standardmäßig listet die Tabelle alle relevanten Objekte nach zugewiesener Größe in absteigender Reihenfolge auf. Sie können auf einen Spaltenkopfnamen klicken, um die Tabelle nach dieser Spalte zu sortieren oder zu ändern, ob die Spalte in aufsteigender oder absteigender Reihenfolge sortiert.
Nutzen Sie dies zu Ihrem Vorteil, wenn Sie die Speichernutzung optimieren und den Speicher effizienter für Hardwareplattformen packen möchten, bei denen das Speicherbudget begrenzt ist.

Memory-Profiling-Techniken und -Workflows
Beginnen Sie mit der Analyse eines Memory-Profiler-Schnappschusses, um Bereiche mit hohem Speicherverbrauch zu identifizieren. Sobald Sie einen Memory Profiler-Schnappschuss aufgenommen oder geladen haben, prüfen Sie auf der Registerkarte Unity Objekte die Kategorien, geordnet nach der größten bis zur kleinsten Speicherplatzgröße.
Projekt-Assets sind oft die höchsten Speicherverbraucher. Suchen Sie im Tabellenmodus nach Texturen, Meshes, Audioclips, Rendertexturen, Shadervarianten und vorab zugewiesenen Puffern. Dies sind oft gute Kandidaten, um mit der Optimierung der Speichernutzung zu beginnen. Der Project Auditor ist hier ein großartiges ergänzendes Tool, da er einige Empfehlungen dazu geben kann, wie die Speichernutzung für Assets reduziert werden kann (vergewissern Sie sich, dass das Asset im Import Settings Inspector richtig eingerichtet ist.)
Speicherlecks finden
Ein Speicherleck ist eine Situation, in der ungenutzte Assets, Objekte oder Ressourcen nicht ordnungsgemäß aus dem Speicher freigegeben werden. Dies kann zu zunehmender Speichernutzung und Leistungsproblemen oder Abstürzen führen.
Ein Speicherleck tritt normalerweise auf, wenn:
- Ein Objekt wird nicht manuell durch den Code aus dem Speicher freigegeben.
- Ein Objekt bleibt unbeabsichtigt im Speicher, weil ein anderes Objekt immer noch eine Referenz darauf enthält.
Der Memory-Profiler verfügt über einen Vergleichsmodus für Snapshots, mit dem Sie Speicherlecks finden können, indem Sie zwei Snapshots über einen bestimmten Zeitraum vergleichen. Dieser Vergleich kann Objekte aufdecken, die im Speicher verbleiben, wenn sie gefunden werden sollten.
Ein häufiges Szenario für Speicherlecks in Unity Spielen ist nach dem Entladen einer Szene. Objekte aus der entladenen Szene werden möglicherweise nicht korrekt als Garbage gesammelt, wenn noch Referenzen darauf vorhanden sind.
Ermittlung wiederkehrender Speicherzuweisungen über die Lebensdauer der Anwendung
Durch den differenziellen Vergleich mehrerer Speicher-Schnappschüsse können Sie die Quelle für kontinuierliche Speicherzuweisungen während der Lebensdauer der Anwendung identifizieren.
In den folgenden Abschnitten finden Sie einige Tipps zur Identifizierung verwalteter Heap-Zuweisungen in Ihren Projekten.

Verwaltete Zuordnungen wie im Memory-Profiler-Modul gezeigt
Das Memory Profiler-Modul im Unity Profiler stellt verwaltete Zuordnungen pro Frame mit einer roten Linie dar. Dies sollte meistens 0 sein, sodass alle Spitzen in dieser Zeile Frames angeben, die Sie auf verwaltete Zuordnungen untersuchen sollten.

Zeitleistenansicht im CPU-Nutzungs-Profiler-Modul
Die Timeline-Ansicht im CPU-Nutzungsprofiler-Modul zeigt Zuordnungen, einschließlich verwalteter, in Pink an, wodurch sie leicht zu verfeinern sind.

Aufruf-Stacks für Zuordnungen
Zuweisungsaufrufstapel bieten eine schnelle Möglichkeit, verwaltete Speicherzuweisungen in Ihrem Code zu finden. Diese bieten das benötigte Detail des Aufrufstapels bei geringerem Overhead als Deep Profiling normalerweise hinzufügen würde, und sie können im Handumdrehen mit dem Standard-Profiler aktiviert werden.
Aufrufstapel für die Zuweisung sind im Profiler standardmäßig deaktiviert. Um sie zu aktivieren, klicken Sie auf die Schaltfläche Call Stacks in der Hauptsymbolleiste des Profiler-Fensters. Ändern Sie die Details-Ansicht in Related Data.
Hinweis: Wenn Sie eine ältere Version von Unity verwenden (vor der Unterstützung von Call Stacks für Zuweisungen), ist Deep Profiling eine gute Möglichkeit, um vollständige Call Stacks zu erhalten, um verwaltete Zuweisungen zu finden.
GC, die in der Hierarchie oder Rohhierarchie ausgewählt wurden, enthalten jetzt ihre Aufrufstapel. Sie können auch die Aufruf-Stacks von GCAlloc-Beispielen im Auswahl-Tooltip in Timeline sehen.

Die Hierarchieansicht im CPU-Nutzungs-Profiler
In der Hierarchieansicht im CPU-Nutzungsprofiler können Sie auf Spaltenüberschriften klicken, um sie als Sortierkriterien zu verwenden. Sortieren nach GC Alloc ist eine großartige Möglichkeit, sich darauf zu konzentrieren.

Projektauditor
Der Projektauditor, der als Paket in Unity 6.1 eingeführt wurde, ist ein leistungsstarkes Analysetool für Unity Projekte, das Entwicklern helfen soll, die Leistung zu optimieren, bewährte Verfahren beizubehalten und potenzielle Probleme und Engpässe in ihren Projekten zu identifizieren.
Project Auditor scannt Ihr gesamtes Projekt und liefert detaillierte Berichte über Ineffizienzen, wie z. B. umfangreiche Skripting-Aufrufe, ungenutzte Assets, übermäßige Entitätszahlen usw.
Der Projektauditor deckt verschiedene Bereiche ab:
Leistungsoptimierung: Es werden Probleme identifiziert, die sich auf die Laufzeitleistung Ihres Projekts auswirken könnten, wie übermäßige Garbage-Generierung, unnötige Objektzuweisungen oder teure Funktionsaufrufe.
Code- und Assetprüfung: Es werden ungenutzte Assets, ineffiziente Codemuster oder veraltete APIs hervorgehoben, die umgestaltet werden können. Dies hilft, die Build-Größe zu reduzieren, die Wartbarkeit des Projekts insgesamt zu verbessern und die Speichernutzung zu optimieren.
Diagnose und bewährte Verfahren: Es enthält Empfehlungen basierend auf bewährten Verfahren von Unity und hebt Fehler oder Warnungen im Zusammenhang mit der Projekteinrichtung hervor, z. B. fehlende Referenzen oder suboptimale Player- oder Qualitätseinstellungen.
Anpassbare Berichte: Es organisiert die Ergebnisse in Kategorien, wodurch Optimierungen einfach priorisiert werden können. Sie können auch benutzerdefinierte Regeln erstellen, um die Analyse auf Ihr spezifisches Projekt oder Ihre Bedürfnisse abzustimmen.
💡Tipps:
- Führen Sie den Projekt-Auditor in wichtigen Phasen der Entwicklung aus (z. B. vor Meilensteinen, Beta-Veröffentlichungen, finalen Builds). Regelmäßige Audits helfen, Leistungsengpässe, ungenutzte Assets oder veralteten Code frühzeitig zu erkennen und zu verhindern, dass Probleme größer werden, wenn Ihr Projekt größer wird.
- Sie können den Projekt-Auditor als Teil Ihrer CI- oder Build-Einrichtung automatisieren (wie hier im Handbuch gezeigt) und die Berichte verwenden, um sicherzustellen, dass niemand Assets oder Code eincheckt, die neue Probleme hinzufügen (unter Verwendung der hier beschriebenen API).
- Sie können Ihre eigenen Regeln hinzufügen, wenn es bestimmte Dinge gibt, die Sie in Ihrem Spiel erfassen möchten, z. B. Textureinstellungen, Größen oder kompliziertere Regeln. Weitere Einzelheiten hierzu finden Sie auf dieser Seite.
Die vom Projekt-Auditor erstellten Berichte sind nach Schweregrad kategorisiert (Haupt-, Mittel- und Info-Bereich). Konzentrieren Sie sich zuerst auf die schwerwiegendsten Probleme, da sie oft leistungskritische Probleme hervorheben, wie z. B. eine übermäßige Speicherzuweisung oder übermäßige Garbage Collection. Sie befinden sich wahrscheinlich auch in Codepfaden, die häufiger aufgerufen werden, wie z. B. Update, wo Leistungsprobleme, die sie mit sich bringen, für die Spieler offensichtlicher werden.
Der Projektauditor prüft auch Einstellungen wie Playereinstellungen und Qualitätseinstellungen und gibt Empfehlungen dazu, was Sie ändern könnten. Verwenden Sie dies, um sicherzustellen, dass Ihre Build-Ziele, Auflösung, Textkompression oder andere Projekteinstellungen für Ihre geplante Plattform optimiert werden.
Domain-Neuladen
Der Unity Editor ermöglicht es Ihnen, Einstellungen für den Play-Modus zu konfigurieren; auf dieser Seite finden Sie weitere Einzelheiten dazu, Sie können aber häufig die Iterationszeit des Editors beschleunigen, indem Sie das erneute Laden der Domäne deaktivieren. Dies setzt Ihren Skripting-Status jedoch nicht mehr jedes Mal zurück, wenn Sie in den Play-Modus wechseln, daher müssen Sie dies manuell in Ihrem Code tun.
Der Codebereich im Project Auditor kann die Skripts in Ihrem Projekt analysieren, um Ihnen zu helfen, überall zu finden, wo Sie Ihre Skriptvariablen zurücksetzen müssen. Es gilt als bewährte Vorgehensweise, alle in der Ansicht „Domain Reload“ angezeigten Probleme zu beheben und dann das Neuladen der Domain zu deaktivieren. Um diese Ansicht mit Daten zu füllen, müssen Sie die Einstellung Roslyn Analyzer verwenden im Fenster Einstellungen aktivieren. Dann können Sie die Liste der Probleme durchgehen und die Anweisungen im Handbuch befolgen, um sie zu beheben. Sobald sie alle adressiert sind, können Sie das Domain Reload deaktivieren, wenn Sie in den Spielmodus wechseln.

Optimierungen für Speicher und GC
Unity verwendet den Boehm-Demers-Weiser Garbage Collector, um den Speicher automatisch zu bereinigen, wenn er für Ihre Anwendung nicht mehr benötigt wird. Der GC führt Ihren Programmcode nicht mehr aus und setzt erst nach Abschluss der Arbeit die normale Ausführung fort.
Die automatische Verwaltung ist zwar praktisch, aber unnötige oder häufige Zuordnungen können zu Leistungseinbußen führen, da der Garbage Collector Ihr Spiel pausieren muss, um ungenutzten Speicher zu bereinigen (auch bekannt als GC Spikes). Hier sind einige häufige Fallstricke, die Sie beachten sollten:
Strings: In C# sind Zeichenketten Referenztypen, keine Werttypen. Das bedeutet, dass jeder neue String dem verwalteten Heap zugewiesen wird, auch wenn er nur vorübergehend verwendet wird. Reduzieren Sie unnötige String-Erstellung oder -Manipulation. Vermeiden Sie das Parsen von zeichenfolgenbasierten Datendateien wie JSON und XML, und speichern Sie stattdessen Daten in ScriptableObjects oder Formaten wie MessagePack oder Protobuf. Verwenden Sie die StringBuilder-Klasse, wenn Sie Strings zur Laufzeit erstellen müssen.
Funktion Unity ruft auf: Manche Funktionen der Unity API erstellen Heap-Zuweisungen, insbesondere solche, die ein Array temporär verwalteter Objekte zurückgeben. Cache-Referenzen auf Arrays, anstatt sie mitten in einer Schleife zuzuweisen. Nutzen Sie auch bestimmte Funktionen, mit denen Sie Garbage vermeiden können. Verwenden Sie beispielsweise GameObject.CompareTag, anstatt eine Zeichenfolge manuell mit GameObject.tag zu vergleichen (da die Rückgabe einer neuen Zeichenfolge Garbage erzeugt).
Sie können auch den Projektauditor verwenden, um diese Alternativen aufzulisten. Dies kann dazu beitragen, dass Sie nach Möglichkeit die nicht zuweisenden Versionen verwenden.
Boxen: Boxing tritt auf, wenn ein Werttyp (z. B. int, float, struct) in einen Referenztyp (z. B. Objekt) umgewandelt wird. Vermeiden Sie es, eine werttypisierte Variable anstelle einer referenztypisierten Variable zu übergeben. Dadurch wird ein temporäres Objekt erstellt und der mitgelieferte potenzielle Garbage konvertiert implizit den Werttyp in ein Typobjekt (z. B. int i = 123; object o = i). Versuchen Sie stattdessen, konkrete Überschreibungen mit dem Werttyp bereitzustellen, den Sie übergeben möchten. Für diese Overrides können auch Generics verwendet werden.
Routinen: Obwohl die Ausbeute keinen Garbage produziert, tut dies das Erstellen eines neuen WaitForSeconds-Objekts. Cache und verwende das WaitForSeconds-Objekt wieder, anstatt es in der Ertragszeile zu erstellen.
LINQ und reguläre Ausdrücke: Beides erzeugt Müll aus dem Hinter-den-Kulissen-Boxen. Vermeiden Sie LINQ und Regular Expressions, wenn die Leistung ein Problem darstellt. Schreiben Sie für Loops und verwenden Sie Listen als Alternative zur Erstellung neuer Arrays.
Generische Sammlungen und andere verwaltete Typen: Deklarieren und füllen Sie keine Liste oder Sammlung in jedem Frame in Update (z. B. eine Liste von Feinden innerhalb eines bestimmten Radius des Spielers). Machen Sie stattdessen die Liste zu einem Mitglied der MonoBehaviour und initialisieren Sie sie in Start. Leeren Sie einfach die Sammlung mit „Löschen“, bevor Sie sie verwenden.
Time Garbage Collection, wann immer möglich
Wenn Sie sicher sind, dass ein Einfrieren der Garbage Collection keinen bestimmten Punkt in Ihrem Spiel beeinflusst, können Sie die Garbage Collection mit System.GC.Collect auslösen. Ein klassisches Beispiel dafür ist, dass der Benutzer sich in einem Menü befindet oder das Spiel anhält, wo es nicht bemerkt wird.
Unter Automatische Speicherverwaltung verstehen finden Sie Beispiele dafür, wie Sie diese zu Ihrem Vorteil nutzen können.
Verwendung des inkrementellen Garbage Collectors zur Aufteilung der GC Arbeitsbelastung
Anstatt eine einzige, lange Unterbrechung während der Ausführung Ihres Programms zu erstellen, verwendet die inkrementelle Garbage Collection mehrere, kürzere Unterbrechungen, die die Arbeitslast auf viele Frames verteilen. Wenn die Garbage Collection zu einer unregelmäßigen Bildrate führt, versuchen Sie es mit dieser Option, um das Problem der GC Spitzen zu reduzieren. Verwenden Sie die Profilanalyse, um den Nutzen für Ihre Anwendung zu überprüfen.
Beachten Sie, dass die Verwendung des GC im inkrementellen Modus einigen C#-Aufrufen Lese-Schreib-Barrieren hinzufügt, was mit einem Overhead verbunden ist, der sich pro Frame des Skripting-Aufruf-Overheads auf bis zu ~1 ms summieren kann. Für eine optimale Leistung ist es ideal, keine GC Allocs in den Haupt-Gameplay-Loops zu haben, sodass Sie den inkrementellen GC nicht für eine flüssige Bildrate benötigen und den GC ausblenden können.Collect wird dort erfasst, wo es einem Benutzer nicht auffällt, beispielsweise beim Öffnen des Menüs oder Laden eines neuen Levels. In solchen optimierten Szenarien können Sie vollständige, nicht inkrementelle Garbage Collections (mit System.GC.Collect()) durchführen.
Weitere Informationen zum Memory-Profiler finden Sie in den folgenden Ressourcen:
Walkthrough und Tutorial zum Memory Profiler
Speichernutzung mit dem Memory-Profiler in Unity verbessern
Memory-Profiler: Das Tool zur Fehlerbehebung bei speicherbezogenen Problemen

Im Hub für Best Practices von Unity finden Sie viele weitere Best Practices und Tipps für fortgeschrittene Unity Entwickler. Wählen Sie aus über 30 Leitfäden aus, die von Branchenexperten, Unity Entwicklern und Technical Artists erstellt wurden und Ihnen helfen, mit den Toolsets und Systemen von Unity effizient zu entwickeln.