2014-02-07 2 views
7

Ich mache eine Analyse über die Zeit in einem kritischen Codeabschnitt.Wie kann man feststellen, ob zwischen zwei Checkpoints eine vollständige Garbage Collection ausgelöst wurde?

//Take a timestamp before 
var before = DateTime.UtcNow; 

DoCriticalMethod(); 

//Take a timestamp after 
var after = DateTime.UtcNow; 

Und irgendwann habe ich einige Werte deutlich höher als andere.

Ich vermute, dass es Garbage Collection ist, also möchte ich die hohen Werte mit der Tatsache korrelieren, dass eine Garbage Collection während des Prozesses aufgetreten ist.

tryed ich dies so weit: Ich nehme den Zähler vor:

//Take the number before 
int gc2CountBefore = GC.CollectionCount(2); 

... 

//Take the number after 
bool hasgc2occured = (GC.CollectionCount(2) - gc2CountBefore) != 0; 

Bin ich es in der guten Art und Weise zu tun?

+2

Sie sollten die 'System.Diagnostics.Stopwatch' Klasse verwenden, um die Ausführungszeit zu messen,' DateTime' hat nicht genug Auflösung. –

+1

Vielen Dank Trevor, ich benutze tatsächlich eine präzise Bibliothek, die direkt die Systemuhr für die maximale Präzision und bessere Leistung aufrufen. Ich habe DateTime in mein Beispiel eingefügt, um einfach zu verstehen. – Thomas

+0

Warum denken Sie, dass Ihre Herangehensweise falsch ist? Es scheint gut zu funktionieren – JaredPar

Antwort

5

Die "RegisterForFullGCNotification" -Methode registriert, dass eine Benachrichtigung ausgelöst wird, wenn die Laufzeit feststellt, dass sich eine vollständige Speicherbereinigung nähert. Diese Benachrichtigung besteht aus zwei Teilen: Wenn sich die vollständige Speicherbereinigung nähert und die vollständige Speicherbereinigung abgeschlossen ist.

Um festzustellen, wann eine Benachrichtigung ausgelöst wurde, verwenden Sie die Methoden "WaitForFullGCApproach" und "WaitForFullGCComplete". In der Regel verwenden Sie diese Methoden in einer while-Schleife, um fortlaufend eine "GCNotificationStatus" -Enumeration zu erhalten, die den Status der Benachrichtigung anzeigt.

Die Methoden "WaitForFullGCApproach" und "WaitForFullGCComplete" sind so konzipiert, dass sie zusammenarbeiten. Die Verwendung von einem ohne den anderen kann zu unbestimmten Ergebnissen führen.

2

Sie können Ihre Anwendung von Mülleinsammlungs während eines bestimmten Abschnitts verhindern:

Prevent .NET Garbage collection for short period of time

ich das versuchen würde, dann Profil wiederholt Code. Wenn Sie nicht so viel Fluktuation sehen, könnte GC dies verursachen.

+0

Interessant, danke für den Trick.+1 – Thomas

1

Es gibt auch einige Stackoverflow Frage zu einem Garbage Collector Monitor:

Monitoring Garbage Collector in C#

Unterm Strich ist es, einen separaten Thread starten und die GC-Ereignisse registrieren:

GC.RegisterForFullGCNotification(int,int) 

Dann können Sie warten auf irgendeine GC-Aktivität:

GCNotificationStatus s = GC.WaitForFullGCApproach(10000); 

Bei einigen Aktivitäten sollten Sie benachrichtigt werden!

+0

Sehr gut, scheint sauberer zu sein, werde ich genauer hinsehen. +1 – Thomas