Wissen von A bis Z

Garbage Collection

Der fleißigste unsichtbare Mitarbeiter Ihrer .NET-Anwendung, der hinter Ihnen aufräumt, bevor der Speicher vor lauter vergessenen Objekten überquillt.

Garbage Collection (GC) bezeichnet in .NET die automatische Speicherverwaltung des Managed Heap durch die Common Language Runtime. Statt Objekte manuell mit free oder delete freizugeben, werden sie vom Garbage Collector erkannt, wenn sie nicht mehr erreichbar sind, und in Sammelläufen aus dem Speicher entfernt. Der .NET-GC ist ein generationaler, kompaktierender Tracing-Garbage-Collector mit den Generationen Gen 0, Gen 1 und Gen 2 sowie einem separaten Large Object Heap (LOH) für Objekte ab 85.000 Byte.

Eingesetzt wird der GC implizit in jeder .NET-Anwendung. Entwickler greifen üblicherweise nur an wenigen Stellen direkt darauf zu: über GC-Konfiguration (Workstation- vs. Server-GC, Concurrent/Background-GC, Region-Based-GC ab .NET 7), über Profiling und Diagnostik (dotnet-counters, PerfView, dotMemory), über IDisposable und using zur deterministischen Freigabe nicht verwalteter Ressourcen sowie über GC.SuppressFinalize, GC.Collect und WeakReferences in spezialisierten Szenarien.

Der Einsatzzweck und das gelöste Problem ergeben sich aus den klassischen Defekten manueller Speicherverwaltung: Memory Leaks, Double-Frees, Use-after-Free, Pufferüberläufe und subtile Aliasing-Bugs. Der GC eliminiert diese Klasse von Fehlern strukturell für reine Managed-Workloads. Generationale Annahmen — die meisten Objekte sterben jung — sorgen dafür, dass der GC im Normalfall sehr günstige Gen-0-Sammlungen ausführt und teure Gen-2-Sammlungen vermeidet. Der kompaktierende Charakter sorgt zudem für gute Cache-Lokalität und vermeidet Heap-Fragmentierung.

Historisch ist der .NET-GC ab dem .NET Framework 1.0 (2002) verfügbar und wurde über die Jahre stark weiterentwickelt: Background-GC ab .NET 4, Server-GC mit mehreren Heaps ab .NET Framework 2.0, Hochlast-Optimierungen für ASP.NET-Szenarien, Pinning-Heap (POH) mit .NET 5 und Region-Based-GC ab .NET 7, der Heap-Segmente flexibler und kleiner organisiert.

Eingeführt und maßgeblich geprägt wurde der .NET-GC von Patrick Dussud, der bereits in den 1990er-Jahren Garbage Collectors für Common Lisp implementiert hatte; in den letzten Jahren stehen Maoni Stephens und das CLR-Performance-Team für die Weiterentwicklung. Maoni Stephens betreibt einen seit Jahren gepflegten Blog (‚Maoni's WebLog'), in dem sie regelmäßig sehr detailliert beschreibt, warum bestimmte Workloads in den Generationen wandern, wie Pause-Zeiten zustande kommen und welche Tuning-Stellschrauben es gibt — diese Posts gelten in der .NET-Community als wesentliche Quelle, um GC-Verhalten in produktiven Anwendungen wirklich zu verstehen, und werden bis heute als Referenz in Performance-Reviews zitiert.

Zurück