views:

207

answers:

6

Hi,

Isn't it possible to get an event when the GC begins? I want to time each individual GC so I can see if pauses in my server are due to GC or something else.

The GC pauses all .NET threads while running, right? (Except the thread that it runs on, of course). How about unmanaged threads?

Thanks!

A: 

unmanaged threads are not affected by the GC.

You can see the GC performance in the performance monitor, here is an article on how to create a system monitor. I think you can get a counter to the GC somehow.

Codeproject

Here is a description of the perf counters used by the GC

GC counters

Andrew Keith
A: 

The GC doesn't issue any events, but you can use a timer and call GC.CollectionCount() to see when a collection has occured.

Guffa
A: 

The % Time in GC performance counter should provide you the data you want.

Martin v. Löwis
+1  A: 

This is what the Profiling API is for. See ICorProfilerCallback2::GarbageCollectionStarted and GarbageCollectionFinished.

As this is a profiler, it obviously isn't suitable for routine use on a production system. But it sounds like you're primarily interested in this for diagnostic purposes anyway. So it might be worth checking whether one of the commercial profilers offers this facility already, or whether the perfmon counters would suffice -- writing your own profiler could be an awfully heavyweight solution!

itowlson
This is what I was looking for! It's mostly a hobby project so the "awfully heavyweight" solution sounds fine (until I get bored and find a new pet project :)Thanks!
+2  A: 

There's a much easier way if all you want to do is figure out when GC is running, it won't tell you exactly when it starts, nor at all when it ends, but if you can see the output from this method I'll describe here when you notice the pauses on your servers, you should be able to figure out if GC is your problem.

Basically, what you do is create a class with a finalizer, construct an object of that class and just drop the reference (ie. don't store it). The object will then be left until GC hits it, where it will be finalized.

The trick now is in the finalizer you log (in whatever way you want to use) that the finalizer has run, and unless the appdomain is in the process of shutting down, you simply construct a new object which you promptly drop the reference to, ready for the next GC.

This works surprisingly well and doesn't need much work from your part.

Here's the class I use:

namespace PresentationMode
{
    /// <summary>
    /// This class is used to get a running log of the number of garbage collections that occur,
    /// when running with logging.
    /// </summary>
    public sealed class GCLog
    {
        #region Construction & Destruction

        /// <summary>
        /// Releases unmanaged resources and performs other cleanup operations before the
        /// <see cref="GCLog"/> is reclaimed by garbage collection.
        /// </summary>
        ~GCLog()
        {
            SiAuto.Main.LogMessage("GARBAGE COLLECTED");
            if (!AppDomain.CurrentDomain.IsFinalizingForUnload() && !Environment.HasShutdownStarted)
                new GCLog();
        }

        #endregion

        #region Public Static Methods

        /// <summary>
        /// Registers this instance.
        /// </summary>
        public static void Register()
        {
#if DEBUG
            if (SiAuto.Si.Enabled)
                new GCLog();
#endif
        }

        #endregion
    }
}

All you have to do is call the .Register() method. Note here that I use SmartInspect as my logging tool so you want to replace the calls involving SiAuto with something else.

In another project, also using SmartInspect, which has the notion of 'watches', where you can send numeric values, and graph them in the logging tool, I sent the values 0, 1, and then 0 in rapid succession, as this would give me a graph that held at 0 at all times, but produced a sharp spike whenever there was a GC running. Couple this with a background thread that monitored CPU usage and memory used gave me very good data to work with.

Lasse V. Karlsen
A: 

You can accuratly monitor and measure GC suspensions using CLR Hosting. You can find an example for exactly that in this post: Accurately Measuring GC Suspensions.

Liran