2009-10-08 14 views
7

GC開始時にイベントを取得できないのですか?個々のGCの時間を計測したいので、サーバーの一時停止がGCなどの原因であるかどうかを確認できます。GC開始および終了イベント

GCは実行中にすべての.NETスレッドを一時停止します。 (それを実行するスレッドを除いて、もちろん)。どうやって管理されていないスレッド?

ありがとうございます!

+0

あなたのコメントをお寄せいただきありがとうございます:-)私はすでに答えを探していますので、私はこれらの提案(最初の3コメント)について既に知っています。私は、GCが稼働している時とそうでない時のタイムラインに表示したい。だから、それが終わったとき、あるいは最後のコレクション以来どれぐらいの時間が経っていたかを知っているなら、それはしません。 私はまだ解決策を見つけることができていないのに驚いていますが、何も存在しなければ、自分でhax0rツールを作成しようとします。 もう一度ありがとう! – Rabbit

答えて

3

これがプロファイリングAPIの目的です。 ICorProfilerCallback2::GarbageCollectionStartedおよびGarbageCollectionFinishedを参照してください。

これはプロファイラーなので、明らかに本番システムでの日常的な使用には適していません。とにかく診断目的のためにこれに主に興味があるように聞こえます。したがって、商用プロファイラーの1人が既にこの機能を提供しているかどうか、またはperfmonカウンターで十分かどうかをチェックする価値があるかもしれません。独自のプロファイラーを書くことは非常に重いソリューションになる可能性があります。

+0

これは私が探していたものです!それは主にホビープロジェクトですので、 "ひどいヘビー級"のソリューションはうまく聞こえます(退屈して新しいペットプロジェクトを見つけるまで:) ありがとう! – Rabbit

0

アンマネージドスレッドは、GCの影響を受けません。

パフォーマンスモニタでGCパフォーマンスを確認できます。システムモニタの作成方法に関する記事があります。私は何とかGCにカウンタを得ることができると思います。ここで

Codeproject

GCは、すべてのイベントを発行しませんが、あなたは、タイマーを使用して見ることがGC.CollectionCount()を呼び出すことができGC

GC counters

1

で使用PERFカウンターの説明ですコレクションが発生したとき。

0

% Time in GCパフォーマンスカウンターで必要なデータを提供する必要があります。

5

GCが実行されているときを把握するだけであれば、開始時と終了時に正確にはわかりませんが、この出力を見ることができればここでは、サーバー上の一時停止に気づいたときに説明しますが、GCが問題であるかどうかを判断できるはずです。

基本的には、ファイナライザを使用してクラスを作成し、そのクラスのオブジェクトを作成し、参照を削除するだけです(つまり、保存しないでください)。オブジェクトはGCがヒットするまで残され、ファイナライズされます。

ファイナライザは、ファイナライザが実行されたときにログを記録します(使用する方法を問わず)。また、appdomainがシャットダウン中でない限り、ただちにドロップする新しいオブジェクトを作成するだけですへの参照、次のGCの準備。

これは驚くほどうまく機能し、あなたの部分から多くの作業を必要としません。

namespace PresentationMode 
{ 
    /// <summary> 
    /// This class is used to get a running log of the number of garbage collections that occur, 
    /// when running with logging. 
    /// </summary> 
    public sealed class GCLog 
    { 
     #region Construction & Destruction 

     /// <summary> 
     /// Releases unmanaged resources and performs other cleanup operations before the 
     /// <see cref="GCLog"/> is reclaimed by garbage collection. 
     /// </summary> 
     ~GCLog() 
     { 
      SiAuto.Main.LogMessage("GARBAGE COLLECTED"); 
      if (!AppDomain.CurrentDomain.IsFinalizingForUnload() && !Environment.HasShutdownStarted) 
       new GCLog(); 
     } 

     #endregion 

     #region Public Static Methods 

     /// <summary> 
     /// Registers this instance. 
     /// </summary> 
     public static void Register() 
     { 
#if DEBUG 
      if (SiAuto.Si.Enabled) 
       new GCLog(); 
#endif 
     } 

     #endregion 
    } 
} 

あなたがしなければならないのは.Register()メソッドを呼び出すことです:

は、ここで私が使用したクラスです。ここではSmartInspectをログツールとして使用して、SiAutoを含むコールを別のものに置き換えたいとします。

別のプロジェクトでは、数字を送信してログツールでグラフを表示できる 'watches'という概念を持つSmartInspectも使用して、0、1、0の値を連続して送りましたこれは常に0に保たれたグラフを私に与えますが、GCが実行されているときはいつも鋭いスパイクを生成しました。これを、CPU使用量と使用されたメモリを監視するバックグラウンドスレッドと組み合わせることで、私は非常に良いデータを得ることができました。

関連する問題