Was könnte diese Verbesserung der Leistung des Müllsammlers in .NET 7.0 (C#, Linux) zu einer Verbesserung der MüllkollekC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Was könnte diese Verbesserung der Leistung des Müllsammlers in .NET 7.0 (C#, Linux) zu einer Verbesserung der Müllkollek

Post by Anonymous »

Wir haben eine große App in C# (ein Multiplayer -Spiel) mit rund 10 Millionen Objekten auf dem Haufen. Der in dieser Frage beschriebene Effekt kann jedoch auch in einer einfachen Test -App mit einer ähnlichen Anzahl von Objekten beobachtet werden. Siehe Beispielcode am Ende der Frage. Beim Erstellen unseres Codes in .NET 7.0 anstelle von .net 8.0 oder .NET 9.0. Wie auf dem Bild zu sehen ist, befindet sich ein .NET 9.0 -Build auf der links , ein .NET 7.0 -Build befindet sich auf der rechten
detaillierte GCConfig -Einstellungen (im Wesentlichen alle Standard): < /p>
ServerGC: False
ConcurrentGC: True
RetainVM: False
NoAffinitize: False
GCCpuGroup: False
GCLargePages: False
HeapCount: 1
GCHeapAffinitizeMask: 0
GCHeapAffinitizeRanges:
GCHighMemPercent: 0
GCHeapHardLimit: 0
GCHeapHardLimitPercent: 0
GCHeapHardLimitSOH: 0
GCHeapHardLimitLOH: 0
GCHeapHardLimitPOH: 0
GCHeapHardLimitSOHPercent: 0
GCHeapHardLimitLOHPercent: 0
GCHeapHardLimitPOHPercent: 0
GCConserveMem: 0
GCName:
< /code>
, um genauer zu sein - und gleichzeitig seltsamer -, die die App -Leistung seit vielen Monaten überwachen und protokolliert. In Die gleiche Netzversion , .NET 7.0.20, von einem Tag bis zum nächsten, reduzierte sich das Zählmuster der GC -Sammlung auf das Niveau in einer plötzlichen Veränderung um 23. März 2025. Weder App -Einstellungen noch Umgebungsvariablen oder andere Konfigurationen wurden zu diesem Zeitpunkt geändert. Die GC -Zählreduktion wird nur in .NET 7 beobachtet. In .NET 8 und .NET 9 Es gab keine Änderung der GC -Sammlungszahl von einem Tag zum nächsten. Daher hat die App Now (seit 23. März 2025) in .NET 8 und .NET 9 eine schlechtere Leistung, und seit diesem Datum haben wir auch die gemeldete GC -Sammlungszahl in alle .NET 7 gebautes Apps auf demselben Betriebssystem (im Vergleich zu .NET 8 oder .NET 9), einschließlich der nachstehenden Beobachtung, bei der die folgenden Aufträge der GC -Aufnahme in der folgenden Aufnahme von. APP: Die Zeitverlust von GC ist geringer, und die Leistung (in Bezug auf die Arbeit pro Sekunde unter Volllast) verbessert sich 10-15%, wie es mit der reduzierten GC-Aktivität zu erwarten wäre. 8. < /p>
Wir haben Daten als Grund ausgeschlossen, da in .NET 8 Daten standardmäßig deaktiviert sind und wir nicht aktiviert haben. Der gleiche Code in der gleichen .NET 7 -Version mit den gleiche Gesamteinstellungen (z. Gleiche Umgebungsvariablen) und eine ähnliche Last. Die Ursache hängt daher weder mit der Instanziierungszahlen noch mit Änderungen des .NET -Bibliothekscodes zusammen. Historisch gesehen ist vor dem 23. März reproduzierbar und kann in einem aktuellen Ubuntu-System beobachtet werden-siehe Details unten
Unter einer älteren Ubuntu-Version (22.04.5) ist die Verringerung der GC-Sammlungereignisse in .net 7 nicht gesehen: Es wird nur gesehen, dass NET 7 unter UBNUNTU 24.04.2. Mit anderen Worten, die ältere /historische .NET 7-Leistung ist in einem Ubuntu 22.04.5 VM weiterhin zu sehen. Intel CPU, keine anderen Apps, die ausgeführt werden, außer für die leichte Überwachungs-/Protokollierungssoftware, die einmal alle 10 ausgelöst wird. und .NET 8, die immer noch an der Analyse der Ausgabe arbeiten. Wie erwartet werden alle Ereignisse durch ein kleines Objekt -Haufen -Zuweisung ausgelöst. Möglicherweise sogar ein Fehler? Aber irgendwie hat sich in gewisser Weise nur für .NET 7 relevant geändert? Es scheint eine verrückte Theorie zu sein, aber wir brauchen hier vielleicht eine verrückte Theorie. Bearbeitet: < /em> Die gleichen Effekte sind in einem neuen Ubuntu 24.04 VM zu sehen, der heute erstellt wurde, keine andere Software, außer für VSCODE. namespace ConsoleApp1;

public class Vec3
{
public float X, Y, Z;

public Vec3(int x, int y, int z)
{
X = x; Y = y; Z = z;
}
}

public class Program
{
public static void Main(string[] args)
{
Console.WriteLine(".NET " + Environment.Version.ToString());
new Program();
}

public List Vectors;

public Program()
{
Vectors = new List();
for (int i = 0; i < 10_000_000; i++)
{
Vectors.Add(new Vec3(i, i, i));
}

for (int i = 0; i < 10_000_000; i++)
{
Vectors = new Vec3(i, i, i);
}

Console.WriteLine($"Gen0: {GC.CollectionCount(0)}");
Console.WriteLine($"Gen1: {GC.CollectionCount(1)}");
Console.WriteLine($"Gen2: {GC.CollectionCount(2)}");
Console.WriteLine($"CollectionTime: {GC.GetTotalPauseDuration().TotalMilliseconds} ms");
}
}
< /code>
Ausgabe in Linux (Ubuntu 24.04.2): < /p>
.NET 7.0.20
Gen0: 12
Gen1: 11
Gen2: 5
CollectionTime: 624.414 ms

.NET 8.0.15
Gen0: 109
Gen1: 59
Gen2: 8
CollectionTime: 1017.408 ms
< /code>
Unter einer älteren Version von Linux (Ubuntu 22.04.5 LTs) ist die .NET 7 -Ausgabe Gen0: 109 Ereignisse, Gen1: 59 Ereignisse, so dass es in älteren Linux -Versionen mit der Ausgabe von .NET 8 übereinstimmt. Dies scheint stark auf etwas zu zeigen, das sich im Betriebssystem ändert, was einige nur auf die .NET 7 -Müllsammlungsauslöser auswirken. < /P>
Für die Vollständigkeit sind unter Windows die Ausgabe für .NET 7 /8 ähnlich wie das Linux .NET 8 -Ausgang. Linux -Version (Ubuntu 24.04 und Derivate). Warum? LIBC6 [/code] ist eine Bibliothek, die viele Funktionen in C ++ unterstützt, und sehr wahrscheinlich, dass der Müllsammlercode von .NET7 davon abhängt.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post