Ich habe diese Antwort auf meinem Blog erneut veröffentlicht: http://dave-black.blogspot.com/2012/04/how-to-determine-which-garbage.html
Sie können feststellen, welche Version des GC Sie verwenden, auf zwei Arten:
- Aufruf der System.Runtime.GCSettings.IsServerGC Eigenschaft
- Anhängen an den Prozess mit WinDbg und Überprüfung, wie viele GC-Threads Sie haben, indem Sie den Befehl "!sos.threads" (ohne Anführungszeichen und gemäß den unten stehenden Kriterien) verwenden...
Sie haben nicht angegeben, um welche Art von App es sich handelt. Wenn Sie eine Konsolen-App, eine WinForm-App oder einen Windows-Dienst ausführen, erhalten Sie den Workstation-GC. Nur weil Sie auf einem Serverbetriebssystem ausgeführt werden, heißt das nicht, dass Sie die Serverversion des GC erhalten. Wenn Ihre App nicht auf einer Multi-Prozessor-Maschine gehostet ist, erhalten Sie standardmäßig den Workstation-GC - Concurrent. Wenn Ihre App auf einer Multi-Prozessor-Maschine gehostet ist, erhalten Sie standardmäßig den Server-GC.
Jede IIS- oder CLR-selbstgehostete App wird standardmäßig im Server-GC-Modus ausgeführt.
Folgendes gilt für jeden .NET-Verwalteten Prozess:
Workstation-GC
- Einzeln-Proc-Maschine
- Immer Threads aussetzen
- 1 Ephemeral GC-Heap (SOH), 1 LOH GC-Heap
- Läuft auf dem Thread, der GC ausgelöst hat
- Threadpriorität entspricht der des Threads, der GC ausgelöst hat
Workstation-GC - Concurrent
- Läuft nur nebenläufig in Gen2/LOH (volle Sammlung)
- Gegensätzlich zum Server-Modus
- Etwas größere Arbeitsmenge
- GC-Thread läuft ab, wenn er eine Weile nicht verwendet wird
- 1 Ephemeral GC-Heap (SOH), 1 LOH GC-Heap
- Gewidmeter GC-Thread
- Threadpriorität ist Normal
Server-GC
- Größere Segmentgrößen
- Schneller als Workstation-GC
- Immer Threads aussetzen
- 1 Ephemeral GC-Heap (SOH) für jeden logischen Prozessor (einschließlich Hyperthreading), 1 LOH GC-Heap für jeden logischen Prozessor (einschließlich Hyperthreading)
- Gewidmete GC-Threads
- Threadpriorität ist THREAD_PRIORITY_HIGHEST
Es gibt nur 1 Finalisierer-Thread pro verwaltetem Prozess, unabhängig vom GC-Modus. Selbst während eines nebenläufigen GC werden verwaltete Threads zweimal ausgesetzt (blockiert), um einige Phasen des GC durchzuführen.
Ein selten bekannter Fakt ist, dass selbst wenn Sie den Servermodus des GC einstellen, es sein kann, dass Sie nicht im Server-GC ausgeführt werden; der GC bestimmt letztendlich, welcher Modus für Ihre App optimal ist und WIRD Ihre Einstellungen außer Kraft setzen, wenn er feststellt, dass Ihre ServerGC-Einstellung sich negativ auf Ihre Anwendung auswirken wird. Auch jede gehostete CLR-App auf einer uniprozessorischen Maschine wird von manuellen GC-Einstellungen außer Kraft gesetzt - in diesem Fall verwendet die CLR immer den Workstation-GC-Modus.
In CLR 4.0 ändert sich nur wenig
- Nebenläufiger GC wird jetzt Hintergrund-GC
- Hintergrund-GC gilt nur für Workstation-GC
- Alt (Nebenläufiger GC):
- Während eines vollen GC sind Zuweisungen bis zum Ende der Größe des ephemeren Segments erlaubt
- Ansonsten setzt alle anderen Threads aus
- Neu (Hintergrund-GC):
- Erlaubt gleichzeitig ephemere GCs mit Hintergrund-GCs, falls erforderlich
- Die Leistung ist deutlich schneller
- Der Server-GC blockiert immer Threads für die Sammlung jeder Generation
In CLR 4.5 ändert sich nur wenig... wieder
- Hintergrund-Server-GC:
- Der Server-GC blockiert nicht mehr. Stattdessen verwendet er dedizierte Hintergrund-GC-Threads, die parallel mit dem Benutzercode ausgeführt werden können - siehe MSDN: Hintergrund-Server-GC
Daher haben ab .NET 4.5 alle Anwendungen Hintergrund-GC verfügbar, unabhängig vom verwendeten GC.
.NET 4.7.1 GC-Verbesserungen
.NET Framework 4.7.1 bringt Änderungen in der Garbage Collection (GC) zur Verbesserung der Zuweisungsleistung, insbesondere für Large Object Heap (LOH)-Zuweisungen. Dies liegt an einem architektonischen Wechsel, um das Zuordnungsschloss des Heaps in 2 für Small Object Heap (SOH) und LOH zu trennen. Anwendungen, die viele LOH-Zuweisungen vornehmen, sollten eine Verringerung der Zuweisungssperre sehen und eine bessere Leistung erfahren. Diese Verbesserungen ermöglichen LOH-Zuweisungen, während der Hintergrund-GC (BGC) SOH bereinigt. Normalerweise wartet der LOH-Allokator die gesamte Dauer des BGC-Sweep-Vorgangs ab, bevor er Anforderungen zur Speicherzuweisung erfüllen kann. Dies kann die Leistung beeinträchtigen. Sie können dieses Problem in den GCStats von PerfView beobachten, wo es eine Tabelle "LOH-Zuweisungspause (durch Hintergrund-GC) > 200 msec Ereignisse" gibt. Der Pausengrund ist "Warten auf BGC, um Freilisten zu durchsuchen". Diese Funktion sollte dazu beitragen, dieses Problem zu mildern.