C# – Are there any events that tell an application when garbage collection has occurred

c++eventsgarbage-collection

I am trying to find a way to know about garbage collection. Either, when it has started, finished or is in process. I really just need some event connected to the collection itself (I think).

My issue is that I have a WeakEventManager (written from scratch) and I have cleanup methods that delete and WeakReferences that are no longer alive (WeakReferences are in a Dictionary).

The issue is that I have to know when it is time to "clean up". It would be nice to cleanup when the collector is doing its thing. Even if it is after the garbage collection, at least the next collection will remove these old objects.

Best Solution

Here's the class I used to log to SmartInspect that GC has occured. You should easily be able to change what this class does.

To get it started, simply call GCLog.Register();.

#region File Header
// This file Copyright © 2007 Lasse Vågsæther Karlsen, All rights reserved.
//
// $Id: GCLog.cs 135 2008-05-28 11:28:37Z lassevk $
#endregion

#region Using

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Gurock.SmartInspect;

#endregion

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
    }
}