代码之家  ›  专栏  ›  技术社区  ›  Vilx-

在.NET中发生垃圾收集时是否有事件?

  •  15
  • Vilx-  · 技术社区  · 15 年前

    我的ASP.NET网站有一个奇怪的减速,我似乎无法追踪。我怀疑GC可能会介入并停止我的线程。要确定每次GC发生时都记录日志是很好的。

    我可以创建一个虚拟对象并在它的finalizer中进行日志记录,但那将是一个一次性的解决方案,而在我的例子中,有几个这样无法解释的暂停。

    有什么想法吗?

    环境是VS2008/.NET 3.5sp1。不,那个 Garbage Collection Notifications 不会这样做,因为它们是一种轮询方法,并且不适用于并发GC。

    5 回复  |  直到 15 年前
        1
  •  9
  •   Lasse V. Karlsen    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();
        }
    }
    

    如果需要,可以添加对停止它的支持,方法是使用一个静态布尔字段,防止它在下次完成时重新启动自身。

        2
  •  2
  •   Oded    15 年前

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

    您可能会收到通知,即将进行完全的垃圾回收

        3
  •  2
  •   Scott Chamberlain    15 年前

    简单的回答是“不,没有GC‘events’,只有GCNotification函数”。但是,您创建了一个包装类,它将侦听 GCNotification

    原因是事件可能在GC完成之前被处理,也可能不被处理。所以他们让你做的是产生一个孩子的线索,睡在上面 WaitForFullGCApproach 或者,如果你不是在寻找一个完整的GC,在GC发生之前做你需要做的任何事情。

        4
  •  1
  •   n8wrl    15 年前

    你监控性能吗?您可以监视CPU—总体和按进程,.NET内存,包括每一代的大小和GC类型的计数。您还可以让perf mon运行并长时间记录以查看趋势。我发现这比“现在就发生”更有用事件。

        5
  •  1
  •   Conrad Frix    15 年前

    ASP.NET Performance Monitoring, and When to Alert Administrators

    它包含一个关于GCcounters的部分,可以查看这些值的含义。例如

    少些会被认为是健康的,但是 比这还大的钉子 不常见。请注意,所有线程都是 在垃圾收集期间挂起。

    你可能还想看看博客 If broken it is, fix it you should 它有许多案例研究,一步一步地说明如何识别一个特定的问题。例如 ASP.NET Case Study: High CPU in GC - Large objects and high allocation rates