C# 是否有任何事件告诉应用程序何时发生垃圾回收?

C# 是否有任何事件告诉应用程序何时发生垃圾回收?,c#,events,garbage-collection,C#,Events,Garbage Collection,我正试图找到一种了解垃圾收集的方法。或者,当它已经开始、完成或正在进行时。我真的需要一些与收藏本身相关的活动(我想) 我的问题是我有一个最弱的VentManager(从零开始编写),我有一些清除方法,可以删除和删除不再存在的WeakReference(WeakReferences在字典中) 问题是我必须知道什么时候该“清理”了。当收集器正在做它的事情时,清理会很好。即使是在垃圾收集之后,至少下一次收集会删除这些旧对象 您可以监视.NET内存性能计数器对象。存在第0代、第1代和第2代集合的计数 通

我正试图找到一种了解垃圾收集的方法。或者,当它已经开始、完成或正在进行时。我真的需要一些与收藏本身相关的活动(我想)

我的问题是我有一个最弱的VentManager(从零开始编写),我有一些清除方法,可以删除和删除不再存在的WeakReference(WeakReferences在字典中)


问题是我必须知道什么时候该“清理”了。当收集器正在做它的事情时,清理会很好。即使是在垃圾收集之后,至少下一次收集会删除这些旧对象

您可以监视.NET内存性能计数器对象。存在第0代、第1代和第2代集合的计数


通常在基于GC的系统上,直接引用GC是一种反模式。在尝试使用清除的WeakReference时,您可能会(给出有限的描述)懒散地进行清理更好。

System.GC类提供RegisterForFullGCNotification方法,该方法允许在垃圾收集即将完成时以及垃圾收集完成时发出通知

这并不理想,因为使用此方法有一些警告,例如必须禁用并发垃圾收集才能使此方法工作

有关完整信息,请参见以下链接:


如果创建一个废弃对象,该对象具有对对象的传出引用,但没有传入引用,即

new MyGcMonitor(this);  // don't store result
如果您确保MyGcMonitor有一个终结器(析构函数),那么在gcfase完成后,将在一个单独的线程上调用该终结器。 终结器可以调用一个方法来告诉您的类终结已经完成

棘手的部分是如果您再次需要它,例如,如果您决定不释放对象。然后,您必须设置一个序列,该序列在运行的GC线程之外创建另一个MyGcMonitor实例。我想您可以使用delegate.invoke,并在该委托中首先调用GC.WaitForPendingFinalizers()


恢复MyGcMonitor也会遇到类似的问题,即稍后删除(静态)引用。

以下是我用来记录到SmartInspect的类,说明发生了GC。您应该能够很容易地更改这个类的功能

要启动它,只需调用
GCLog.Register()

#区域文件头
//本文件版权所有©2007 Lasse Vågsæther Karlsen,保留所有权利。
//
//$Id:GCLog.cs1352008-05-2811:28:37Z lassevk$
#端区
#区域使用
使用制度;
使用System.Collections.Generic;
使用系统文本;
使用系统诊断;
使用Gurock.SmartInspect;
#端区
名称空间表示模式
{
/// 
///此类用于获取发生的垃圾回收次数的运行日志,
///使用日志记录运行时。
/// 
公共密封类日志
{
#区域建设与破坏
/// 
///释放非托管资源并在
///通过垃圾收集回收。
/// 
~GCLog()
{
SiAuto.Main.LogMessage(“垃圾收集”);
如果(!AppDomain.CurrentDomain.IsFinalizingForUnload()&&!Environment.HashutdownStarted)
新GCLog();
}
#端区
#区域公共静态方法
/// 
///注册此实例。
/// 
公共静态无效寄存器()
{
#如果调试
如果(SiAuto.Si.已启用)
新GCLog();
#恩迪夫
}
#端区
}
}

在低优先级线程中,您可以使用此简单的静态方法检查应用程序是否需要清理

    private static bool NeedsCleaning ()
    {
        if (DummyRef.IsAlive) {
            return false;
        }
        DummyRef = new WeakReference (new object ());
        return true;
    }

+1“当您尝试使用清除的WeakReference时,您最好只是懒洋洋地清理。”这是真的,但这可以在另一个线程中完成。正如我所说的,这并不理想,但它确实提供了一种“框架友好”的方式来接收来自垃圾收集器的通知,而无需使用“黑客”代码;通常,当人们谈论GC时,他们对更昂贵的集合感兴趣
    private static bool NeedsCleaning ()
    {
        if (DummyRef.IsAlive) {
            return false;
        }
        DummyRef = new WeakReference (new object ());
        return true;
    }