2010-09-09 55 views
13

我的ASP.NET網站有一個奇怪的減速,我似乎無法跟蹤。我懷疑GC可能會踢我並阻止我的線程。要知道每次GC發生時都記錄下來。在.NET中發生垃圾回收時是否存在事件?

我可以做一個虛擬對象,並做記錄在它的終結,但隨後這將是一個一次性的解決方案,而在我的情況下,有幾個這樣的可解釋暫停。

任何想法?

補充:環境是VS2008/.NET 3.5 SP1。不,Garbage Collection Notifications不會這樣做,因爲它們是輪詢方法,不適用於併發GC。

+0

這取決於您使用的是哪個版本的框架。 – 2010-09-09 15:32:23

+0

雖然有趣的問題 – serg10 2010-09-09 16:51:11

回答

2

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

可以通知您,一個完整垃圾回收將至

+0

這不一定會發生,它更像是投票,而我需要一個事件。 – 2010-09-09 16:25:41

1

你監控穿孔 - 週一?您可以觀察整個CPU和整個過程的.NET內存,包括每一代的大小和GC類型的數量。您還可以讓perf-mon運行並記錄更長時間以查看趨勢。我發現這比離散的「現在正在發生的事情更有用!」事件。

+1

具體而言,您可能需要.NET CLR內存性能對象。從那裏你可以得到特定應用程序池的GC計數器。 – 2010-09-09 16:53:39

1

簡單的答案是「否有沒有GC‘事件’只有GCNotification功能」。但是,您創建一個包裝類,它將偵聽GCNotification,並且該包裝器可以觸發事件,但是沒有您想要的簡單事件解決方案。

原因是這個事件可能會或可能不會在GC完成之前處理。所以他們要做的就是生成一個子線程,如果你不想要一個完整的GC,在WaitForFullGCApproach或極點上睡覺,並且在GC發生之前做你需要做的任何事情。

0

您可能需要閱讀這篇文章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

8

這是一個簡單的技巧。它可能不是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(); 
    } 
} 

如果你願意,你可以添加由具有靜態布爾字段,防止其重新啓動其本身在未來定稿停止對它的支持。

希望這有一些幫助。