Skip to content

Beiträge

Garbage Collection-Typen in .Net Core

2. September 2019 • 4 min Lesezeit

Garbage Collection-Typen in .Net Core

Speicherverwaltung in modernen Sprachen ist oft ein Nachgedanke. Praktisch gesehen schreiben wir Software, ohne auch nur einen Gedanken an den Speicher zu verschwenden. Das funktioniert gut für uns, aber es gibt immer Ausnahmen…

In Kalifornien gibt es umfangreiche Anforderungen an die Finanzberichterstattung für Local Education Agencies (LEA). Eine LEA kann ein County, ein Schulbezirk, eine Charter-Schule oder eine einzelne Schule sein. Die meisten LEAs erstellen ihre eigenen Finanzberichte, die normalerweise auf Excel basieren. Es ist keine Überraschung, dass jeder Bericht unterschiedlich ist. Um dieses Problem zu lösen, beauftragte das California Board of Education die Entwicklung von Software zur Generierung von Finanzberichten.

Ich war Teil des Entwicklungsteams.

Mein erster Halt waren die Test-Logs. Die Logs von Ed-Pro deuteten auf hohe Speichernutzung hin – könnte es ein Speicherleck sein? Ein Ingenieur beobachtete, dass Ed-Pro’s Berechnungen große Mengen an kurzlebigem Speicher verwendeten. Wenn der Speicher nicht schnell bereinigt wurde, könnte es wie ein Speicherleck aussehen.

Ed-Pro basiert auf .Net Core, Microsofts Multi-Plattform-Framework. In .Net Core ist der Speicher in drei Kategorien unterteilt: Kurzlebig (Gen0), mittelfristig (Gen1) und langlebig (Gen2). Gen0 ist für kurzlebige Daten, die schnell den Gültigkeitsbereich verlassen, Gen1 ist für mittelfristig lebenden Speicher, der etwas länger bestehen bleibt und schließlich auch den Gültigkeitsbereich verlässt, und Gen2 ist langlebiger Speicher, der möglicherweise für die gesamte Lebensdauer der Anwendung bestehen bleibt. Gen0-Speicher wird ständig freigegeben, Gen1 wird weniger häufig freigegeben als Gen0, und Gen2 wird noch weniger häufig freigegeben als Gen1.

Die einzige sichere Möglichkeit, die Speichernutzung von Ed-Pro zu verstehen, war, es zu profilieren. Unten ist ein Screenshot mit dotMemory von JetBrains.

Wie erwartet fanden wir große Mengen an Gen0-Speicher (das Blau), so viel, dass es schien, als könnte die Garbage Collection nicht mithalten. Eine Strategie zur Kompensation großer Speichermengen führte dazu, dass die Garbage Collection zwischen der Vergrößerung des Speicherplatzes (Hinzufügen von mehr Speicher für die Nutzung durch die Anwendung) und dessen Bereinigung oszillierte. Während der Bereinigungszyklen ist die Anwendung nicht responsiv.

Anfangs waren wir ratlos – ist nicht der Zweck der GC, den Speicher ordentlich zu halten? Zwei Artikel waren instrumental für unser Verständnis, wie Garbage Collection in .Net funktioniert: Der Artikel Troubleshooting high memory usage with ASP.Net Core on Kubernetes von Mark Vincze und Fundamentals of Garbage Collection von Microsoft. Beide sind großartige Lektüren und brachten Klarheit in die Speichernutzung von Ed-Pro.

Hier ist eine Zusammenfassung dessen, was wir gelernt haben: Es gibt zwei Arten von Garbage Collection in .Net: Server Garbage Collection und Workstation Garbage Collection.

Server Garbage Collection macht ein paar Annahmen: Erstens ist reichlich Speicher verfügbar und zweitens sind die Prozessoren Multi-Core und schnell. Beides kann wahr sein, aber wir leben in einer Welt von virtuellen Maschinen und Docker, wo es wahrscheinlicher ist, dass beide Annahmen falsch sind.

Server Garbage Collection ermöglicht es dem Speicher, sich aufzubauen. Irgendwann macht es eines von zwei Dingen: Es vergrößert entweder den Speicherplatz, um Speicher wachsen zu lassen, oder es gibt verwaisten Speicher frei. Wenn es sich entscheidet, Speicher freizugeben, startet die Garbage Collection den Prozess auf einem hochpriorisierten Thread. Der hochpriorisierte Thread hat eine höhere Priorität als die Anwendung; wenn die Maschine schnell ist, sollte die Bereinigung nicht bemerkt werden. Wenn nicht, führt dies dazu, dass die Anwendung anhält, bis die Bereinigung abgeschlossen ist.

Workstation Garbage Collection funktioniert anders. Es läuft kontinuierlich und gibt Speicher auf einem Thread mit der gleichen Priorität wie die Anwendung frei. Dies bedeutet, dass es auch mit der Anwendung um Ressourcen konkurriert, was zu Anwendungsverlangsamung führen kann. Der Vorteil ist, dass die Speichernutzung der Anwendung ziemlich niedrig bleiben kann, besonders wenn sie große Mengen an Gen0 verwendet.

Standardmäßig führt .Net Core, wenn es einen Server erkennt, den Server Garbage Collection-Typ aus, was bei unserer Anwendung der Fall war. Um den Workstation Garbage Collection-Typ auszuführen, fügen Sie das folgende Snippet zu Ihrer Projektdatei hinzu:

  <PropertyGroup> 
    <ServerGarbageCollection>false</ServerGarbageCollection>
  </PropertyGroup>

Wir nahmen diese Konfigurationsänderung an Ed-Pro vor. Mit dotMemory profilten wir Ed-Pro’s Speicher mit aktivierter Workstation Garbage Collection und luden die gleichen Bildschirme wie im vorherigen Test. Hier sind die Ergebnisse:

Die Speichernutzung ist erheblich gesunken. Die Gen0-Zuordnungen sind praktisch nicht vorhanden. Über die Unterschiede in der Grafik hinaus erreichte die Server Garbage Collection-Speichernutzung 1 GB, während die Workstation Garbage Collection etwa 200 MB erreichte.

Jede Anwendung ist unterschiedlich. Unsere Anwendung verwendete eine Menge temporärer Daten und nutzte daher eine Menge Gen0-Speicher. Ihre Anwendung kann längerfristigen Speicher wie Gen1 oder Gen2 nutzen, in welchem Fall Server Garbage Collection sehr sinnvoll ist. Mein Rat ist, Ihren Speicher unter verschiedenen Bedingungen zu profilieren, um eine Vorstellung davon zu bekommen, wie Speicher verwendet wird, und dann zu entscheiden, welcher Modus am besten für Ihre Anwendung geeignet ist.

Autor: Chuck Conway ist ein KI-Ingenieur mit fast 30 Jahren Erfahrung in der Softwareentwicklung. Er entwickelt praktische KI-Systeme – Content-Pipelines, Infrastruktur-Agenten und Tools, die echte Probleme lösen – und teilt seine Erkenntnisse unterwegs. Verbinden Sie sich mit ihm in den sozialen Medien: X (@chuckconway) oder besuchen Sie ihn auf YouTube und auf SubStack.

↑ Nach oben

Das könnte dir auch gefallen