我的ASP.NET网站有一个奇怪的减速,我似乎无法追查。我怀疑GC可能会开始并停止我的线程。要确定每次GC确实发生时都要记录它。
我可以创建一个虚拟对象并在其终结器中进行记录,但那将是一次性解决方案,而在我的情况下,有几个这样无法解释的暂停。
有什么想法吗?
已添加:环境为VS2008 / .NET 3.5 SP1。不,Garbage Collection Notifications不会这样做,因为它们是一种轮询方法,并不适用于并发GC。
答案 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