.NETプログラムからグローバルルーツを取得します
質問
私は最近、生産作業のためにAntsプロファイリングツールの使用を開始しました。彼らの素晴らしさに驚かされるだけでなく、私は彼らがどのように機能するのか疑問に思わずにはいられませんでした。たとえば、最も有用な機能の1つでは、異なるタイプの値への参照の数を備えたランニングプログラムのグローバルなルーツを視覚化することができます。
このツールはその情報をどのように保持しますか?
解決
(完全な開示:私はビジュアルスタジオプロファイラーチームに参加していますが、以下の情報は公開されています)
これを行うには、ターゲットにしているプロセス内で実行されるCLRプロファイラーを作成することで、これを行うことができます。 CLRプロファイラーは、ランタイムによってインスタンス化されるC ++ comオブジェクトです COR_PROFILER
と COR_PROFILING_ENABLED
環境変数が設定されています(参照してください ここ)。 2つのメインがあります CLRプロファイリングインターフェイス, 、 具体的には、 ICorProfilerCallback
と ICorProfilerInfo
. ICorProfilerCallback
CLRがサブスクライブする特定のイベント(モジュールの負荷、関数JITコンプリエーション、スレッド作成、GCイベント)について通知するために使用するものです。 ICorProfilerInfo
プロファイラーは、ロードされたアセンブリのスレッド、モジュール、タイプ、メソッド、およびメタデータに関する追加情報を取得するために使用できます。このインターフェイスはあなたのものです たぶん......だろう 割り当てられたタイプに関するシンボル情報を取得するために使用します。
プロファイラーのインプロセスを使用すると、GCを強制することができます ICorProfilerInfo::ForceGC
. 。 GCが完了すると、プロファイラーは経由で通知されます ICorProfilerCallback2::GarbageCollectionFinished
, 、そして、あなたは介してルート参照を取得します ICorProfilerCallback2::RootReferences2
. 。ルート参照情報を組み合わせるとき ICorProfilerCallback::ObjectReferences
, 、.NETアプリケーションの完全なオブジェクト参照グラフを取得できます。
を使用して、より多くのリアルタイム情報を取得できます ICorProfilerCallback::ObjectAllocated
個々のCLRオブジェクトがいつ作成されるかを決定するコールバック。ただし、これは高価になる可能性があります。これは、割り当てられた各オブジェクトに少なくとも追加の関数呼び出しが発生しているためです。 CLRが割り当てられたものをマッピングして、個々のオブジェクトを追跡できます ObjectID
あなた自身の内部IDに。 an ObjectID
特定のオブジェクトの場合、ガベージコレクションが発生するにつれて変化する可能性があるため、一時的なポインターがあり、コンパクション中にオブジェクトが移動する可能性があります。このプロセスが示されています ここ. 。情報を使用できます ICorProfilerCallback::MovedReferences
移動するオブジェクトを追跡します。
上記のコールバックをアクティブにするには、CLRプロファイリングAPIに興味があることを伝える必要があります。これを指定することでこれを行うことができます COR_PRF_MONITOR_GC
と COR_PRF_MONITOR_OBJECT_ALLOCATED
イベントの一部として、電話をかけるとき ICorProfilingInfo::SetEventMask
.
DavidBromanはCLRプロファイラーの開発者であり、 彼のブログ あなたが遭遇するかもしれないすべてのクレイジーな落とし穴や問題を含む、一般的にプロファイリングに関する多くの素晴らしい情報があります。
他のヒント
アリのようなプロファイラーは、CLR自体が提示する「プロファイリングAPI」を使用しています。たとえば、オブジェクトが割り当てられたときに発生するAPIコールバックメソッドがあります。 ObjectAllocated(). 。同様に、メソッドが入力されるとき、スレッドが作成されるときなどのイベントがあります。
元のプロファイリングAPIは、icorprofilercallbackと呼ばれます。後のバージョンは、coreprofilercallback2およびcoreprofilercallback3と呼ばれます。それらの名前をグーグルで検索すると、探している答えが正確に見つかります。 CodeProjectでは、実用的な例を見ることができます。 カスタム.NETプロファイラーの作成
最終メモ:APIは、C#やVB.NETなどの管理コードから使用できません。 EG CやC ++のような管理されていないコードからのみ利用できます。したがって、C#アプリは、このAPIを使用して、たとえば独自の動作とオブジェクトを調べることができません。