9

Welche Art von Optimierungsmustern kann verwendet werden, um die Leistung des Garbage Collectors zu verbessern?Wie kann die Garbage Collection-Leistung verbessert werden?

Mein Grund zu fragen ist, dass ich viel Embedded-Software mit dem Compact Framework. Auf langsamen Geräten kann die Garbage-Collection zu einem Problem werden, und ich möchte die Zeiten reduzieren, in denen der Garbage Collector antritt, und wenn das der Fall ist, möchte ich, dass es schneller beendet wird. Ich kann auch sehen, dass die Arbeit mit dem Garbage Collector statt dagegen helfen könnte, alle .NET- oder Java-Anwendungen zu verbessern, insbesondere bei Heavy-Duty-Webanwendungen.

Hier sind einige meiner Gedanken, aber ich habe keine Benchmarks gemacht.

  • Wiederverwendung temporäre Klassen/Arrays (niedrig halten Zuweisung count)
  • die Menge an lebenden Objekten auf ein Minimum zu halten (schnellere Sammlungen)
  • versuchen structs zu verwenden anstelle von Klassen
+0

Ich würde vorschlagen, den Titel zu ändern "... verbessern die .NET Compact Frameworok ...", so dass die Suchergebnisse ein bisschen weniger irreführend sind. – cdiggins

Antwort

12

Der Schlüssel ist zu verstehen, wie der CF GC für Zuordnungen funktioniert. Es ist ein einfacher Mark-and-Sweep-Generierungs-GC mit spezifischen Algorithmen für das, was einen GC auslöst und was nach der Sammlung eine Verdichtung und/oder Pitching verursacht. Es gibt fast nichts, was Sie auf App-Ebene tun können, um den GC zu steuern (die einzige verfügbare Methode ist Collect, und ihre Verwendung ist ziemlich begrenzt, da Sie die Komprimierung ohnehin nicht erzwingen können).

Die Wiederverwendung von Objekten ist ein guter Anfang, aber einfach die Objektanzahl gering zu halten, ist wahrscheinlich eines der besten Werkzeuge, da alle Wurzeln für jeden Sammelvorgang durchlaufen werden müssen. Es ist eine gute Idee, diesen kurzen Weg zu gehen. Wenn Sie durch die Verdichtung getötet werden, hilft die Vermeidung der Segmentfragmentierung. Objekte> 64k können dabei hilfreich sein, da sie ihr eigenes Segment bekommen und anders behandelt werden als kleinere Objekte.

Um wirklich zu verstehen, wie der CF GC funktioniert, würde ich empfehlen, die MSDN Webcast on CF memory management zu beobachten.

2

One Wichtig ist, die Lebensdauer Ihrer Objekte so kurz wie möglich zu halten.

+1

Nicht unbedingt. Viele kleine, kurzlebige Objekte werden GC-Thrash viel schlimmer als nur ein paar langlebige, große Objekte verursachen und würde sein Problem tatsächlich verschlimmern. Dies ist * nicht * ein Desktop-Computer mit Desktop-Speicher und Prozessorressourcen – ctacke

+0

Ich denke, der Rat von MS ist es, Objekte so kurzlebig wie möglich zu halten. Objekte, die Generation 0 überleben, sind problematischer. –

+0

Ich habe einen Verweis auf einen MSDN-Artikel dazu gefunden. Es scheint sich um eine 10-mal Verlangsamung pro Speichergeneration zu handeln. Der Artikel ist unter: http://msdn.microsoft.com/en-us/magazine/dd882521.aspx#id0400035 –

2

Das Problem struct vs class ist ein komplexes Problem. Sie könnten zum Beispiel mit einem Los mehr Stapelspeicherplatz enden. Und Sie wollen sicherlich keine veränderlichen Strukturen. Aber die anderen Punkte scheinen vernünftig, solange Sie das Design nicht aus der Form biegen, um es anzupassen.

[Bearbeiten] Eine andere häufige Gotcha ist String-Verkettung; Wenn Sie eine Verkettung in einer Schleife durchführen, verwenden Sie StringBuilder, wodurch ein Los von Zwischenzeichenfolgen entfernt wird. Es könnte sein, dass GC damit beschäftigt ist, all die verlassenen Hüllen deiner Strings zu sammeln?

2

Eine andere Option wäre, den Müll während Nicht-Spitzenzeiten in Ihrer Anwendung mithilfe von GC.Collect() manuell zu erfassen (vorausgesetzt, dies ist in CF verfügbar). Dies könnte die Objekte reduzieren, die später in Ihrer Anwendung für die Bereinigung benötigt werden.

0

Ich hörte eine .NET Rocks Show auf Rotor 2.0. Wenn Sie wirklich Hardcore sind, können Sie Rotor herunterladen, die Quelle optimieren und Ihren eigenen modifizierten Garbage Collector verwenden.

In jedem Fall hat dieser Podcast einige gute Informationen auf dem GC. Ich empfehle dringend, es zu hören.

3

Der wichtigste Aspekt ist die Minimierung der Zuteilungsrate. Wann immer ein Objekt zugewiesen wird, benötigt es GC später. Wenn das Objekt jetzt klein oder kurzlebig ist, wird es in der jungen Generation genagelt werden (vorausgesetzt, dass der GC generational ist). Große Objekte neigen dazu, direkt in die Arena zu gehen. Aber das Sammeln zu vermeiden, ist noch besser.

Auch wenn Sie Dinge auf den Stapel werfen können, werden Sie viel weniger Druck auf den GC genießen. Sie könnten versuchen, mit GC-Optionen zu spielen, aber ich denke, Sie würden viel besser mit einem Zuweisungsprofiler in der Hand geholfen werden, so dass Sie die Stellen finden können, die die Probleme machen.

Die Sache, vor der man sich hüten sollte, ist das Gewicht von Standardbibliotheken und Frameworks. Sie wickeln ein paar Objekte ein und es wird sich ziemlich schnell füllen. Denken Sie daran, wann immer etwas auf den GC-Heap geht, benötigt es normalerweise etwas mehr Platz für die GC-Buchhaltung.So sind Ihre 1000 individuell zugewiesenen Zeiger viel größer als ein Array/Vektor der gleichen Zeiger, da diese die GC-Buchhaltung teilen können. Auf der anderen Seite wird letzteres wahrscheinlich noch lange am Leben bleiben.

+2

Die CF ist nicht generationsübergreifend - es ist rein markieren und Sweep. – ctacke

Verwandte Themen