Verstoß gegen die Regeln der Unity Garbage Collection

Es war einmal ein Einheitsspielprogrammierer namens Lancelot. Eine sehr leidenschaftliche, würde ich sagen. Er wusste es noch nicht, aber irgendwann würde er sich der dunkelsten Seite der Unity-Müllsammlung stellen.

Bild

Lancelot war immer auf der Suche nach immer größeren Titeln, an denen er arbeiten konnte. Und so hat er hart gearbeitet, um seine große Chance in der Spieleindustrie zu bekommen.

Es war nicht einfach, das wusste er.

Diese Stellen in der Spielebranche waren und sind einer kleinen Minderheit von Spielprogrammierern vorbehalten. Und er war sich sowieso nicht sicher, ob er den Standards entsprechen würde.

Aber er beharrte und schärfte seine Programmierkenntnisse weiter.

Lancelot begann an kleinen Spielen zu arbeiten. Vielleicht würde er irgendwann die große Chance bekommen, die er suchte, dachte er.

Es vergingen Jahre, bis er die Gelegenheit bekam, auf die er wartete. Er wurde gebeten, ein großes VR-Spiel auf eine mobile Plattform zu portieren. So aufgeregt Lancelot auch war, er fragte sich immer wieder, ob er für die Aufgabe gut genug war . Es war entmutigend, aber er nahm die Herausforderung an. Er wusste, dass er nur daraus wachsen konnte.

Lancelots größte Sorge war die Notwendigkeit, die Leistung des Spiels massiv zu verbessern. Tatsächlich war es eine doppelte Herausforderung. Für eine deutlich weniger leistungsfähige Plattform musste er die Leistung um 20% verbessern .

Nach Monaten ununterbrochener Arbeit gelang es ihm schließlich, das Spiel so zu optimieren, dass eine absolut solide Ausgangsleistung erzielt wurde.

Ein unerwartetes Problem war jedoch gleich um die Ecke ...

Der Unity-Profiler zeigte ihm alle paar Sekunden einen deutlichen Rückgang der Framerate. Und das beunruhigte ihn, denn das würde ihm nicht erlauben, das Spiel auszuliefern. Die Veröffentlichung des Spiels war in Gefahr. Das machte es ihm äußerst unangenehm.

Aufgrund seiner früheren Erfahrungen wurde Lancelot schnell des Müllsammlers verdächtigt. Schließlich wusste er, dass das allzu häufige Zuweisen von temporärem Speicher im Spiel diese Leistungsspitzen verursachen könnte. Genau wie der Mülleimer in der Küche eines jeden Menschen ist es an der Zeit, ihn zu reinigen, wenn er 80% seiner Kapazität erreicht.

Und so verbrachte er Tage damit, die lästigen Speicherzuordnungen zu bekämpfen. Er führte alle möglichen Optimierungen durch. Objektpools, Daten-Caching, Datenstrukturoptimierungen ...

Die Optimierung dieser Tage brachte ihn auf der Performance-Reise ein Stück weiter. Lancelot war stolz auf seine Arbeit, aber seine Besorgnis wuchs erst, als er den Müllmann noch alle 15 Sekunden laufen sah.

Das Spiel in VR mit diesen Leistungseinbrüchen zu spielen, würde die Leute irgendwie blass aussehen lassen.

"Wie konnte das passieren?", Fragte er sich.

Mit mehr Geduld und Graben entdeckte Lancelot eine zweite Quelle von Speicherzuordnungen, die er zuvor nicht gesehen hatte. Diese fanden in einer Drittanbieter-Bibliothek statt .

Er warf einen Blick darauf und stellte bald fest, dass er sich in der schlimmsten Situation befand, die es je gab: Diese Bibliothek war eine geschlossene Quelle. Nicht nur das, er versuchte auch, Unitys inkrementellen Müllsammler zu verwenden, aber er konnte es sich nicht leisten, seinen Leistungspreis zu zahlen.

Lancelot gingen die Optionen aus.

Er fühlte sich verzweifelt, schaffte es aber, ruhig zu bleiben. Immerhin war er in schlimmeren Situationen.

Er könnte die Bibliothek zurückentwickeln und die Speicherzuordnungsoptimierungen selbst vornehmen. Das Problem war, dass die Lizenz solche Dinge nicht erlaubte. Und er war zu jung, um ins Gefängnis zu gehen.

Die zweite Option, die er in Betracht zog, bestand darin , eine Menge Speicher auf dem Heap vorab zuzuweisen . Er wusste, dass die Einheit den Speicherbereinigungsprozess auslöste, als der Heap-Verbrauch einen bestimmten Prozentsatz erreichte. Wenn er also den Haufen vergrößert, sollte er mehr Zeit zwischen den Müllsammlungen haben.

Leider war das immer noch nicht genug.

Es fühlte sich langsam an, als hätte er keine Kontrolle über die Situation. Es war hart, aber er blieb bestehen .

So kam Lancelot auf eine verrückte Idee . Was ist, wenn er die Müllabfuhr komplett deaktiviert hat? War das überhaupt möglich? Er fühlte in seinen Knochen, wie riskant eine solche Idee war. Er wollte nicht die Möglichkeit hinzufügen, dass das Spiel an unvorhersehbaren Punkten abstürzt. Das letzte Mal, als er nachschaute, war das kein Spaß für die Spieler. Vielleicht haben sich die Zeiten geändert, aber sicherer als leid.

Darüber hinaus machte er sich Sorgen, die Veröffentlichung des Spiels zu verzögern. Er wollte nicht, dass seine Spieler diesen Titel zu Weihnachten verpassen. Er erinnerte sich, wie viel Spaß es ihm in diesen Ferien gemacht hatte, EverQuest zu spielen. Das würde er den Spielern nicht nehmen.

An diesem Punkt hatte er keine andere Wahl, als den Garbage Collector zu deaktivieren.

Er ging in den Forschungsmodus und stellte fest, dass er die Speicherbereinigung tatsächlich manuell deaktivieren konnte. Er führte Dutzende von Experimenten durch, um zu sehen, wie lange das Spiel dauern würde, ohne dass der Speicher knapp würde. Er hat alle möglichen Tests durchgeführt, um das System zu belasten. Überall klicken, herumlaufen und springen, zwischen verschiedenen Anwendungen wechseln.

Zahlen tauchten in seiner Tabelle auf: 25 Minuten, 28 Minuten, 30 Minuten ... Er bemerkte auch, wie sich die Nutzung des Heapspeichers im Laufe der Zeit erhöhte, um sicherzugehen, dass er niemals ein sicheres Budget überschreiten würde.

Mit diesen Zahlen stellte Lancelot eine großzügige Sicherheitsmarge auf und bereitete einen Prototyp vor . Er führte die Speicherbereinigung manuell während des Ladevorgangs und alle paar Minuten durch.

Er hatte wieder Hoffnung.

Er bat QA höflich, das Spiel Dutzende Male durchzugehen.

Der Speicher war immer im Rahmen des Budgets. Keine Abstürze. Keine Nebenwirkungen

Diese lange Reise brachte ihn an den Punkt, an dem er das Spiel ausliefern konnte.

Und raten Sie mal was? Hunderte von Spielern freuen sich jetzt über die Weihnachtszeit.

Am Anfang war er mit dieser Lösung nicht zufrieden. Es war ein riskanter Schritt und er wusste es. Aber er konnte es schaffen.

Lancelot lernte, sich mit dem Unbehaglichen wohl zu fühlen. Er lernte, pragmatischer zu sein . Weil es Zeiten gibt, in denen ein Programmierer sein muss.

Läutet irgendetwas in der Geschichte eine Glocke? Wenn ja, ist Ihre Intuition wahrscheinlich richtig.

Dieser Programmierer war ich.

So können Sie den Garbage Collector für die von Ihnen benötigten Zeiten verwalten:

Dieses Code-Snippet zeigt Ihnen, wie Sie automatische Garbage Collections deaktivieren. Der GC-Prozess wird jede Minute manuell und möglicherweise während Bildschirmübergängen (Überblenden auf Schwarz) ausgeführt.

Seien Sie sich der möglichen Nebenwirkungen bewusst:

  • Abstürze : Wenn Sie nicht auf Nummer sicher gehen, wird Ihnen der Arbeitsspeicher ausgehen. Schlimmer noch, das Betriebssystem kann Ihr Spiel beenden, wenn Sie zwischen Anwendungen wechseln
  • Längere Speicherbereinigungszeiten : Durch Erhöhen des Heapspeichers werden zukünftige Speicherbereinigungen langsamer

Wenn Sie großzügige Mengen an Müll produzieren müssen, ist dies eine einfache Methode, die einfach funktioniert:

public class GenerousGarbageCreator : MonoBehaviour { [SerializeField] private int garbageCreationRate = 1024; private static int[] _garbage; void Update() { _garbage = new int[garbageCreationRate]; } } 

Folgendes erhalten Sie im Profiler:

Bild
Unity Garbage Collection: Zeitbasierter manueller Trigger

Dort sehen Sie eine zunehmende Speichernutzung. Die zunehmende Heap-Nutzung wird als "Mono" hervorgehoben. Zum Glück führen wir den manuellen Garbage Collector alle 3 Sekunden aus.

Sie können diesen Abfallerzeugungs-Räumungszyklus deutlich im Profilerdiagramm sehen. Für diejenigen Spieleentwickler, die Physik studiert haben, ist es möglicherweise eine Sägezahnwellenform.

Wenn Sie den Quellcode dieses Projekts möchten, wissen Sie, wo Sie ihn finden können (Spoiler: hier).

Für allgemeinere Speicheroptimierungen sind Sie möglicherweise an Unity Addressables interessiert. Mit adressierbaren Elementen können Sie den Gesamtspeicherbedarf reduzieren, sodass Sie weniger häufig Garbage Collections auslösen können. Dies verringert wiederum die Leistungsspitzen, die Ihre Spieler erfahren.

Ich freue mich darauf, 2020 mit Ihnen allen zusammenzuarbeiten.
Ruben

Source: https://habr.com/ru/post/de484710/


All Articles