Laden...

Garbage Collector auf Performance optimieren

Erstellt von steffen_dec vor 11 Jahren Letzter Beitrag vor 11 Jahren 2.154 Views
S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 11 Jahren
Garbage Collector auf Performance optimieren

Hallo Zusammen,

wir haben momentan ein größeres Problem mit unserem Programm.

Wir erhalten von außen alle 150ms drei Aufgaben diese Aufgaben werden getrennt voneinander abgearbeitet (parallel in verschiedenen Threads), zum Schluß führt der Thread der am längsten gebraucht hat, die Ergebnisse zusammen und gibt diese weiter.

Die Auswertung von einem Thread benötigt je nachdem zwischen 60ms bis 120ms.

Wenn die Anlage ideal läuft erhalten wir wie gesagt alle 150ms drei neue "Aufgaben". D.h. für den Garbage Collector bleibt hier relativ wenig Zeit.

Nun haben wir den Phänomen dass ein Thread ab und zu deutlich mehr Zeit benötigt, ich befürchte dass es auf den Garbage-Collector zurückzuführen ist.

Ich habe nun verschiedenste Sachen ausprobiert und komme so langsam nicht drauf wie man es lösen könnte!? Habe versucht nach jeder Auswertung den GC.Collect manuell aufzurufen (gen 2 und forced/optimized), hat nicht zum Erfolg geführt.

Eingesetzt wird Visual Studio 2010 (C#) mit .Net 4.0 auf einem Win7 x64 mit 16GB Ram.

Was ich im ProcessExplorer beobachtet habe dass der Speicherverbrauch von unserem Programm nur bis max 1,1 GB steigt und dann wieder abgebaut wird obwohl noch genug Speicher verfügbar ist. Natürlich braucht der GC dann deutlich länger je mehr Speichermüll sich angesammelt hat...

In .Net 4.0 wurde doch der GC optimiert sodass er die Threads nicht mehr anhält die die Objekte erstellt haben!? Muss man diese Funktion erst noch einstellen?

Hat nun jemand eine Idee wie man GC steuern sollte damit dieser die anderen Threads nich abbremst?

(Überall ein Dispose/Finalize aufzurufen ist nicht möglich da hier eine Bibliothek von Dritthersteller verwendet wird und diese wohl auch nicht sauber programmiert ist...)

Vielen Dank im Voraus für eure Ideen und Anregungen!

Gruß
Steffen

W
872 Beiträge seit 2005
vor 11 Jahren

An Deiner Stelle wuerde ich mal den Server Mode von der Garbage Collection versuchen.
Ausserdem wuerde ich mir im Prozess-Explorer die Zeit anzeigen lassen, die Dein Programm prozentual im Garbage Collector verbraucht. Ausserdem solltest Du auf die Anzahl der Objekte in den verschiedenen Generationen achten.
Wieviele Kerne hat denn die Maschine, auf der die Aufgaben laufen?
Vom Programm her wuerde ich klarer eine Boss/Work Crew Aufteilung machen. Das Zusammenfuehren sollte in einem eigenen Thread laufen, so dass die Work Crew nie wartet.

zum Schluß fuehrt der Thread der am längsten gebraucht hat, die Ergebnisse zusammen und gibt diese weiter deutet auf einen potentiellen Engpass dort hin.

Edit:
Ich halte es fuer schlecht, den Garbage Collector selber ausfuehren - der optimiert sein Verhalten automatisch anhand des bisherigen Verhaltens Deines Programmes. Wenn Du ihn direkt aufrufst, wird er mehr Ressourcen brauchen, da er oefters als noetig laeuft.

G
497 Beiträge seit 2006
vor 11 Jahren

blöde Frage: warum ist es schlimm, wenn die Verarbeitung hin und wieder länger dauert? Muss eine Rückmeldung innerhalb der 150 ms irgendwohin erfolgen oder ist die Anwendung einfach nur nicht darauf ausgelegt, einen zweiten Aufgabensatz zu beginnen, wenn der erste noch nicht abgeschlossen ist?

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 11 Jahren

Danke für die Beiträge!

@weismat:
Über dem Server-Mode vom GC habe ich auch gelesen, aber ist es nicht so dass dieser erst aktiviert werden kann, wenn man mehr als eine physikalische CPU hat?

The server GC is available only on multiprocessor computers. It creates a separate managed heap and thread for each processor and performs collections in parallel. During collection, all managed threads are paused (threads running native code are paused only when the native call returns). In this way, the server GC mode maximizes throughput (the number of requests per second) and improves performance as the number of processors increases. Performance especially shines on computers with four or more processors.

In dem PC ist ein i7-3930K (6x3,2Ghz) verbaut.

Vom Programm her wuerde ich klarer eine Boss/Work Crew Aufteilung machen. Das Zusammenfuehren sollte in einem eigenen Thread laufen, so dass die Work Crew nie wartet.

Dies werde ich überprüfen ob es machbar ist, die Zusammenführung auszulagern...

@GarlandGreene:
Die Auswertung muss nach 150ms fertig sein, da spätestens dann die Rückmeldung (Ergebnis) bekannt sein muss und weitergegeben werden soll. Sonst wird Ausschuß produziert wo kein Ausschuß ist...

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo steffen_dec,

In .Net 4.0 wurde doch der GC optimiert sodass er die Threads nicht mehr anhält die die Objekte erstellt haben!? Muss man diese Funktion erst noch einstellen?

ja und nein. Viele Verbesserungen sind automatisch aktiv. Aber eine besonders niedrige Latenz muss man manuell einschalten, siehe Latenzmodi (.NET 4.0) und Latenzmodi (aktuelle Version).

Ich halte es fuer schlecht, den Garbage Collector selber ausfuehren - der optimiert sein Verhalten automatisch anhand des bisherigen Verhaltens Deines Programmes. Wenn Du ihn direkt aufrufst, wird er mehr Ressourcen brauchen, da er oefters als noetig laeuft.

Im Grunde ist das richtig, aber wenn man weiß, man hat noch z.B. 50ms bis die nächsten Arbeitsaufträge eintreffen, dann kann man den Mehraufwand (sowohl hinsichtlich des Programmieraufwands als auch hinsichtlich des höheren Ausfürhungsaufwands) durchaus in Kauf nehmen, wenn der Rechner in dieser Zeit sowieso nichts anderes zu tun hat und man dafür die Wahrscheinlichkeit dafür reduziert, dass der GC anspringt, obwohl dafür gerade keine Zeit ist.

herbivore

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 11 Jahren

Hallo herbivore,

danke für deinen Hinweis.
Über diese Latenzmodis habe ich auch schon gelesen.
Allerdings denke ich nicht dass es hier das richtige ist, damit verschiebt man doch nur den GC-Lauf der dann unter Umständen erst die nächste Abarbeitung wieder abbremsen könnte...

Oder was passiert wenn gerade der GC aufräumt und ich in den anderen Threads den LatencyMode verstelle auf Low!? wird der GC dadurch sofort angehalten oder läuft dieser zu Ende und verzögert somit meine Auswertung?

F
10.010 Beiträge seit 2004
vor 11 Jahren

Anstatt rumzuspekulieren was da nicht oder zu spät freigegeben wird würde ich eher mal einen MemoryProfiler anwerfen und schauen was es tatsächlich ist.

(Überall ein Dispose/Finalize aufzurufen ist nicht möglich da hier eine Bibliothek von Dritthersteller verwendet wird und diese wohl auch nicht sauber programmiert ist...)

Ist kein Grund die eigenen Sachen genauso schlampig zu machen.

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo steffen_dec,

Latenzmodis [...] damit verschiebt man doch nur den GC-Lauf

es gibt ja mehrere Latenzmodi. Bei GCLatencyMode.LowLatency sagt man - so wie ich es verstanden habe - wirklich "mach jetzt für einen Moment nichts, was meine Threads blockiert", aber bei GCLatencyMode.SustainedLowLatency geht es - so wie ich es verstanden habe - darum, dass die Zeiten für die Blockierung von Thread dauerhaft minimiert werden. Siehe auch The .NET Framework 4.5 includes new garbage collector enhancements for client and server apps.

herbivore

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 11 Jahren

ich hätte vielleicht sagen sollen dass ich nicht so einfach auf .Net 4.5 updaten kann, dies wird von der genutzen Bibliothek nicht unterstützt.

Und wie es aussieht gibt es dieses "SustainedLowLatency" erst in der Version 4.5.

ich werde jetzt mal mit dem Profiler schauen ob ich irgendwelche ungünstige Stellen im Programm finde wo der Speicher nicht sofort freigegeben wird und somit der GC länger benötigt...

6.911 Beiträge seit 2009
vor 11 Jahren

Hallo steffen_dec,

wenn du ein VS mit dem Performance Profiler solltest du dort den Concurrency Visualizer verweden. Ohne die genaue Ursache zu kennen, kann das Problem nicht behoben werden.
Siehe z.B. auch Case Study: Parallelism and Memory Usage

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"