.NET中是否存在垃圾收集的事件?

时间:2010-09-09 15:30:37

标签: .net events garbage-collection

我的ASP.NET网站有一个奇怪的减速,我似乎无法追查。我怀疑GC可能会开始并停止我的线程。要确定每次GC确实发生时都要记录它。

我可以创建一个虚拟对象并在其终结器中进行记录,但那将是一次性解决方案,而在我的情况下,有几个这样无法解释的暂停。

有什么想法吗?

已添加:环境为VS2008 / .NET 3.5 SP1。不,Garbage Collection Notifications不会这样做,因为它们是一种轮询方法,并不适用于并发GC。

5 个答案:

答案 0 :(得分:9)

这是一个简单的伎俩。它可能不是100%准确,但它可能已经足够好了。

如果你能接受最终确定的通知,那么你可以使用一种简单的方法。

创建一个对象,不要保留对它的引用。完成对象后,引发事件,然后构造另一个对象。您也不会保留对此对象的引用,但它将一直存在,直到下次执行完整的集合。

这是一个对象:

public class GCNotifier
{
    public static event EventHandler GarbageCollected;

    ~GCNotifier()
    {
        if (Environment.HasShutdownStarted)
            return;
        if (AppDomain.CurrentDomain.IsFinalizingForUnload())
            return;
        new GCNotifier();
        if (GarbageCollected != null)
            GarbageCollected(null, EventArgs.Empty);
    }

    public void Start()
    {
        new GCNotifier();
    }
}

如果需要,可以通过使用静态布尔字段来添加对停止它的支持,以防止它在下次完成时重新启动。

希望这有一些帮助。

答案 1 :(得分:2)

Perhpas this文章(垃圾收集通知)将有所帮助。

  

您可以收到有关完整垃圾收集正在接近的通知

答案 2 :(得分:2)

简单的答案是“没有GC'事件'只有GCNotification功能”。但是,您创建了一个将侦听GCNotification的包装器类,并且该包装器可以触发事件,但是没有像您正在寻找的简单事件解决方案。

原因是在GC完成之前可能会或可能不会处理事件。所以他们所做的就是产生一个子线程,如果你不是在寻找一个完整的GC,你可以在WaitForFullGCApproach或者极点上睡觉,并在GC发生之前做你需要做的任何事情。

答案 3 :(得分:1)

你监控性能吗?您可以观察CPU - 整体和进程,.NET内存,包括每代的大小和GC类型的计数。您还可以让perf-mon运行并长时间记录以查看趋势。我觉得这比离散更有用'它现在正在发生!'事件

答案 4 :(得分:1)

您可能希望阅读ASP.NET Performance Monitoring, and When to Alert Administrators

上的这篇文章

它包括一个关于GCcounters的部分,以及值的含义。例如

  GC中的

%时间。时间的百分比   花在执行最后的垃圾   采集。平均值为5%或   少被认为是健康的,但是   比这更大的尖峰不是   罕见。请注意,所有线程都是   在垃圾收集期间暂停。

您可能还想查看博客If broken it is, fix it you should它有一些案例研究,分步介绍如何识别特定问题。例如ASP.NET Case Study: High CPU in GC - Large objects and high allocation rates