Wird bei der Verwendung eines Delegates ein Müll erstellt?

7

Ich arbeite an einem Spiel für die Xbox360, mit XNA. Auf der Xbox schneidet der Garbage Collector im Vergleich zu dem auf einem PC eher schlecht ab. Daher ist es für ein reibungslos funktionierendes Spiel unerlässlich, den erzeugten Müll auf ein Minimum zu reduzieren.

Ich erinnere mich, einmal gelesen zu haben, dass das Aufrufen eines Delegierten Müll verursacht, aber jetzt für das Leben von mir kann keine Verweise auf Delegaten finden, die Müll verursachen. Habe ich das gerade erfunden oder sind Delegierte chaotisch?

Wenn die Delegierten unordentlich sind, gibt es Bonuspunkte, um einen Workaround zu empfehlen.

%Vor%

Mein Code sieht momentan so aus, dass die einzige Lösung, die ich mir vorstellen kann, um Delegierte loszuwerden, darin besteht, eine Klasse zu übergeben, die eine Schnittstelle IValueCalculator erbt, und dann kann ich die Methode auf dieser Schnittstelle aufrufen wirklich sehr ordentlich, aber!

    
Martin 17.10.2009, 17:36
quelle

3 Antworten

10

Ein Delegat ist selbst ein Objekt. Wenn Sie also einen Delegaten, vielleicht für eine anonyme Methode, erstellen und diesem eine andere Methode zum Ausführen übergeben und den Delegaten nicht für zukünftige Referenz speichern, dann dass Müll produziert.

Zum Beispiel:

%Vor%

In diesem Fall wird ein neues Delegatobjekt erstellt, aber über den Aufruf von ForEach hinaus wird nicht darauf verwiesen und ist daher für die Garbage Collection geeignet.

Das Aufrufen von Delegaten erzeugt jedoch selbst keinen Müll mehr, als wenn Sie eine andere Methode des gleichen Typs aufrufen würden. Wenn Sie beispielsweise einen Delegaten aufrufen, der einen Object -Parameter verwendet und einen Wert für Int32 übergibt, wird dieser Wert eingerahmt, aber das würde passieren, wenn Sie eine normale Methode genauso aufrufen würden.

Das Verwenden von Delegaten sollte also in Ordnung sein, aber das übermäßige Erstellen von Delegatobjekten wird ein Problem darstellen.

Bearbeiten : Ein guter Artikel zur Speicherverwaltung für Xbox und XNA finden Sie hier: Verwaltete Code-Leistung auf der Xbox 360 für XNA: Teil 2 - GC und Tools . Beachten Sie dieses Zitat:

  

Wie kontrolliert man die GC-Latenz? Wie NetCF für Geräte ist die Xbox GC nicht generationsübergreifend. Das bedeutet, dass jede Sammlung eine vollständige Sammlung auf dem verwalteten Heap ist. Daher stellen wir fest, dass die GC-Latenz ungefähr linear zur Anzahl der Live-Objekte ist ... und fügen Sie dann die Kosten für die Heap-Komprimierung hinzu. Unsere Benchmarks zeigen, dass der Unterschied zwischen tiefen Objekthierarchien und oberflächlichen Objekthierarchien vernachlässigbar ist. Daher ist es hauptsächlich die Anzahl der Objekte, auf die es ankommt. Kleine Objekte sind auch etwas billiger als große Objekte.

Wie Sie sehen können, versuchen Sie zu vermeiden, viele unnötige Objekte zu erstellen, und Sie sollten besser sein.

    
Lasse Vågsæther Karlsen 17.10.2009, 17:59
quelle
14

In der Desktop-Umgebung ist Müll praktisch frei . Was Sie sich Sorgen machen müssen, ist, wie viel non-marbage Sie produzieren. Denken Sie daran, wie der Garbage Collector funktioniert: Er markiert zuerst alle bekannten Objekte, dann löscht er die Markierung auf allen Live-Objekten und komprimiert die Live-Objekte. Der teure Schritt dort ist "Markierung der Live-Objekte". Den Müll zu zerstören ist billig; Es identifiziert die Live-Objekte, die teuer sind, und diese Kosten hängen von der Anzahl der Live-Objekte ab, die Sie haben (und der Komplexität ihrer Referenztopologie), und nicht von der Anzahl der toten Objekte, die Sie haben.

Auf XBOX- und anderen kompakten Frameworks wird der Garbage Collector jedoch recht häufig ausgeführt und wird häufiger ausgeführt, wenn neue Zuordnungen erstellt werden. Sie müssen sich also sorgen, dass Sie auch mit dem Erstellen von Unfällen zu tun haben. Sie möchten sowohl das Live-Set klein halten (um eine Sammlung billig zu machen) als auch keine neuen Zuordnungen vornehmen (weil das Collections auslöst).

Erstellen ein Delegat reserviert zwar Speicher, aber ruft ist nichts anderes als eine Methode namens Invoke für eine Klasse aufzurufen. Ein Delegat ist nicht viel mehr als eine Klasse mit einer Methode namens Invoke, die beim Aufruf sofort eine andere -Methode aufruft.

Unabhängig davon, ob Sie ein Problem mit der Speicherleistung haben, dann ist es das Richtige, den Speicherprofiler zu entfernen und damit Ihr Programm zu analysieren. Casting über zufällig, sich zu fragen, ob dies oder das geschieht, um Speicher zuzuweisen, ist wie zu versuchen, Ihren Garten mit Nagelschere zu jäten; Es braucht viel Zeit und erreicht nicht wirklich Ihre Ziele. Verwenden Sie einen Profiler, um Ihre Leistung zu analysieren und festzustellen, wo sich die Probleme befinden, und beheben Sie sie anschließend.

    
Eric Lippert 17.10.2009 19:11
quelle
1

Die Erstellung von Delegaten erzeugt Müll, wie bereits von anderen bemerkt.

In Ihrem Beispiel erzeugt die Verwendung von params argent wahrscheinlich auch Müll.

Erwägen Sie die Bereitstellung von Überladungen, ohne das Schlüsselwort params zu verwenden.

Das ist der Grund, warum Überladungen mit unterschiedlicher Anzahl von Argumenten normalerweise in Bibliotheksmethoden zusammen mit demjenigen, das params Schlüsselwort verwendet, existieren:

Siehe String.Format-Methode (String, Object [])

%Vor%     
George Polevoy 11.11.2014 09:03
quelle