Ich habe eine Anwendung, die eine große Anzahl kleiner Objekte verarbeitet, z. 2000 Nachrichten pro Sekunde. Eine Nachricht ist ungefähr 100 Bytes, vielleicht weniger. Die Anwendung lief unter Last sechseinhalb Stunden lang und hatte in dieser Zeit 264 416 0 th Sammlungen, 166 699 1 st gen und 69 608 2 nd gen. Dies sind 11,6, 7,3 und 3 Sammlungen pro Sekunde.
Die Frage ist, wie man die Müllsammlung weniger häufig macht?
UPD: Anwendung ist ein Server, der Nachrichten von WCF empfängt, sie durch mehrere Verarbeitungsmodule packt und sie in der Datenbank speichert.
Ich hatte den Eindruck, dass GC sich nach einiger Zeit anpassen und die Generationsgröße erhöhen sollte, aber das ist offensichtlich nicht der Fall.
UPD 2 : wie in leppies Antwort GC im Server-Modus macht in der Tat 10 Mal weniger Sammlungen. Auch scheint es (wie Richter es beschreibt), dass häufige Sammlungen keine schlechte Sache sind.
Sie erhalten ca. 10 mal weniger GCs, wenn Sie gcServer="true"
in der app.config aktivieren. Beachten Sie jedoch, dass dies die Leistung nicht verbessert, und Sie haben wahrscheinlich die Latenz in Ihrer Anwendung erhöht, wenn es sich um eine Desktop-Anwendung handelt.
Hier ist app.config Einstellung:
%Vor%Was lässt Sie glauben, dass dies Auswirkungen auf Sie hat? Insbesondere Gen-0-Sammlungen sind sehr, sehr billig - und zu fördern.
Ich würde mehr auf "" werfen. "Was dazu führen könnte, dass einige dieser Anfragen gen-0 in gen-1 verschwinden lassen; klammere ich mich unnötig an irgendein Objekt, zum Beispiel über ein Ereignis? ".
Natürlich ist eine andere Sache, die Sie sich ansehen sollten: Gibt es Orte, an denen Sie unnötige Objekte vermeiden können, zum Beispiel:
StringBuilder
sein könnte? byte[]
kurz in einer Methode verwendet, wo diese byte[]
könnte als Scratch-Bereich übergeben oder aus einem Pool? new Regex("some literal")
, das in ein statisches Feld umgewandelt und für die Leistung kompiliert werden kann
Die Anzahl der Gen # 0 Sammlungen ist ungefähr richtig. Gen # 1 und # 2 sind zu hoch, diese Objekte leben zu lange. Vielleicht steckst du sie in eine Schlange und sie sitzen dort für eine Weile, bevor sie verarbeitet werden. Sonst ein Zeichen, dass Sie kurz vor der Sättigung stehen. Abgesehen davon, dass sie schneller verarbeitet werden, könnte das Poolen der Puffer hilfreich sein.
Haben Sie erwogen, Werttypen anstelle von Referenztypen zu verwenden? Es könnte eine gute Option sein, wenn die "Objekte" vorübergehend sind und nur während der Verarbeitung benötigt werden. Werttypen (Strukturen) werden auf dem Stapel zugeordnet und benötigen daher keine Sammlung (wie Klasseninstanzen).
Ihr Problem ist nicht der Garbage Collector, aber Sie haben zu viele Objekte. Wenn Ihr Prozess seriell ist und Sie nicht alle diese Objekte gleichzeitig im Speicher haben müssen, versuchen Sie, ihn erneut zu verwenden, anstatt ihn zu erstellen und zu löschen. Wenn Leistung Ihr Ziel ist, verwenden Sie andere Arten von Strukturen, um Daten zu speichern, z. B. Arrays, Speicherströme oder andere Sammlungen, aber keine Objektgruppen.
Vielleicht sollten Sie einen Objektpool oder Fliehgewichte verwenden. Mehr wiederverwendbare Objekte führen oft zu weniger Müll und machen GC weniger häufig.
Tags und Links .net garbage-collection