7

I am doing analysis on the time spend in a critical section of code.

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

DoCriticalMethod();

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

And sometime I have some values clearly higher than others.

I suspect that it is Garbage collection, so I want to correlate the high values with the fact that a Garbage collection occured during the process.

I tried this so far : I take the counter before :

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

...

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

Am I doing it in the good way?

Thomas
  • 5,603
  • 5
  • 32
  • 48
  • 2
    You should use the `System.Diagnostics.Stopwatch` class to measure the execution time, `DateTime` doesn't have enough resolution. – Trevor Pilley Feb 07 '14 at 16:29
  • 1
    Thank you Trevor, I am actually using a precise library that directly call the system clock for the maximum precision and better performance. I put DateTime in my example just to be simple to understand. – Thomas Feb 07 '14 at 16:32
  • Why do you think your approach is wrong? It appears to work just fine – JaredPar Feb 07 '14 at 16:54
  • Could be gc, it is entirely indistinguishable from any other reason that your thread gets pre-empted. Operating system scheduling decisions up front. The signal you get is very jittery, pretty important that you take many samples and don't cherry-pick the good ones because that just gives unrealistic expectations. – Hans Passant Feb 07 '14 at 17:44

3 Answers3

5

The "RegisterForFullGCNotification" method registers for a notification to be raised when the runtime senses that a full garbage collection is approaching. There are two parts to this notification: when the full garbage collection is approaching and when the full garbage collection has completed.

To determine when a notification has been raised, use the "WaitForFullGCApproach" and "WaitForFullGCComplete" methods. Typically, you use these methods in a while loop to continually obtain a "GCNotificationStatus" enumeration that shows the status of the notification.

The "WaitForFullGCApproach" and the "WaitForFullGCComplete" methods are designed to work together. Using one without the other can produce indeterminate results.

Kostadin
  • 405
  • 3
  • 14
2

You can prevent your application from garbage collecting during a certain section:

Prevent .NET Garbage collection for short period of time

I'd try that, then profile your code repeatedly. If you don't see as much fluctuation, it might be GC causing it.

Community
  • 1
  • 1
Curtis Rutland
  • 776
  • 4
  • 12
1

There is also some StackOverFlow question about a garbage collector monitor:

Monitoring Garbage Collector in C#

Bottom line is start a separate thread and to register to the GC events:

GC.RegisterForFullGCNotification(int,int)

Then you can wait for any GC activity:

GCNotificationStatus s = GC.WaitForFullGCApproach(10000);

If there is some activity you should get notified!

Community
  • 1
  • 1
toATwork
  • 1,335
  • 16
  • 34