この記事の対象: ✔️ バージョン 3.0.47001 以降のバージョン
注意
macOS dotnet-dump は、.NET 5 以降のバージョンでのみサポートされています。
インストール
をダウンロードしてインストールするには、次の 2 つの方法があります。
dotnet グローバル ツール:
NuGet パッケージの最新のリリース バージョンをインストールするには、次のように dotnet tool install コマンドを使用します。
dotnet tool install --global dotnet-dump直接ダウンロード:
ご利用のプラットフォームに適したツールの実行可能ファイルをダウンロードします。
オペレーティングシステム (OS) プラットフォーム Windows x86x64ArmArm-x64 Linux x64ArmArm64musl-x64musl-Arm64
注意
x86 アプリ上で を使用するには、対応する x86 バージョンのツールが必要です。
構文
dotnet-dump [-h|--help] [--version] <command>
説明
dotnet-dump グローバル ツールは、ネイティブ デバッガーを使用せずに、Windows、Linux、および macOS 上のダンプを収集して分析する方法です。 このツールは、 が完全に動作しない Alpine Linux などのプラットフォームで重要です。 ツールでは、SOS コマンドを実行してクラッシュとガベージ コレクター (GC) を分析できますが、これはネイティブのデバッガーではないため、ネイティブ スタック フレームの表示などの操作はサポートされていません。
オプション
--versiondotnet-dump ユーティリティのバージョンを表示します。
-h|--helpコマンド ライン ヘルプを表示します。
コマンド
| コマンド |
|---|
| dotnet-dump 収集 |
| dotnet-dump analyze |
| dotnet-dump ps |
dotnet-dump 収集
プロセスからダンプをキャプチャします。
構文
dotnet-dump collect [-h|--help] [-p|--process-id] [-n|--name] [--type] [-o|--output] [--diag] [--crashreport]
オプション
-h|--helpコマンド ライン ヘルプを表示します。
-p|--process-id <PID>ダンプを収集するプロセスの ID 番号を指定します。
-n|--name <name>ダンプを収集するプロセスの名前を指定します。
--type <Full|Heap|Mini>プロセスから収集する情報の種類を決定する、ダンプの種類を指定します。 次の 3 種類があります。
- - モジュール イメージを含むメモリをすべて含む最大のダンプ。
- : モジュールの一覧、スレッドの一覧、すべてのスタック、例外情報、ハンドル情報、およびマップされたイメージを除くすべてのメモリを含む、大規模で比較的包括的なダンプです。
- : モジュールの一覧、スレッドの一覧、例外情報、およびすべてのスタックを含む小さいダンプです。
- - モジュール リスト、スレッド リスト、例外情報、すべてのスタック、および PII が削除された小さなダンプ。
指定しない場合の既定は、 です。
-o|--output <output_dump_path>収集したダンプを書き込む完全なパスとファイル名。 dotnet プロセスを実行しているユーザーに指定のディレクトリに対する書き込み許可が与えられるようにします。
指定していない場合は、次になります。
- Windowsの既定値は .\dump_YYYYMMDD_HHMMSS.dmp です。
- Linux および macOS での既定は、./core_YYYYMMDD_HHMMSS です。
YYYYMMDD は、年/月/日で、HHMMSS は時間/分/秒です。
--diagダンプの収集の診断ログを有効にします。
--crashreportクラッシュ レポートの生成を有効にします。
注意
Linux と macOS 上でこのコマンドを使用するには、ターゲット アプリケーションと で同じ 環境変数が共有されることが前提とされています。 それ以外の場合、このコマンドはタイムアウトします。
注意
を使用してダンプを収集するには、ターゲット プロセスを実行しているユーザーと同じユーザーとして、またはルートとしてそれを実行する必要があります。 それ以外の場合、このツールでターゲット プロセスとの接続を確立することはできません。
注意
完全ダンプまたはヒープ ダンプを収集すると、ターゲット プロセスの実質的な仮想メモリに OS がページングされる可能性があります。 メモリ制限が適用されたコンテナーでターゲット プロセスが実行されている場合、メモリ使用量が増加すると、制限を超えた場合に OS がコンテナーを終了する可能性があります。 メモリ制限が十分に高く設定されていることを確認するためのテストをお勧めします。 もう 1 つのオプションは、環境でサポートされている場合は、ダンプ収集の前に制限を一時的に変更または削除することです。
dotnet-dump analyze
ダンプを検索する対話型シェルを開始します。 このシェルでは、さまざまな SOS コマンドを受け入れます。
構文
dotnet-dump analyze <dump_path> [-h|--help] [-c|--command]
引数
<dump_path>分析のためにファイルをダンプするパスを指定します。
オプション
-c|--command <debug_command>起動時にコマンドを実行します。 1 つの呼び出しでこのパラメーターの複数インスタンスを使って、コマンドを連鎖させることができます。 コマンドは、コマンド ラインで指定した順番に実行されます。 このコマンドの後に dotnet dump を終了する場合は、最後のコマンドを 'exit' にする必要があります。
SOS コマンドを分析する
| コマンド | 機能 |
|---|---|
analyzeoom |
GC ヒープへの割り当て要求で発生した最後の OOM の情報を表示します。 |
clrmodules |
プロセス内のマネージド モジュールを一覧表示します。 |
clrstack |
マネージド コードのみのスタック トレースを提供します。 |
clrthreads |
実行中のマネージド スレッドを一覧表示します。 |
clru |
マネージド メソッドの注釈付き逆アセンブリを表示します。 |
| または | メモリの内容をダンプします。 |
dbgout |
内部 SOS ログを有効/無効 () にします。 |
dso |
現在のスタックの範囲内で見つかったすべてのマネージド オブジェクトを表示します。 |
dumpalc |
指定したオブジェクトが読み込まれる先の収集可能な AssemblyLoadContext に関する詳細を表示します。 |
dumparray |
マネージド配列に関する詳細を表示します。 |
dumpasync |
ガベージ コレクトされたヒープ上の非同期状態機械に関する情報を表示します。 |
dumpassembly |
アセンブリに関する詳細を表示します。 |
dumpclass |
指定されたアドレスにある 構造体に関する情報を表示します。 |
dumpconcurrentdictionary |
同時実行辞書の内容を表示します。 |
dumpconcurrentqueue |
同時実行キューの内容を表示します。 |
dumpdelegate |
デリゲートに関する情報を表示します。 |
dumpdomain |
すべての AppDomain または指定されたドメイン内のすべてのアセンブリに関する情報を表示します。 |
dumpgcdata |
GC データに関する情報を表示します。 |
dumpgen |
指定した世代のヒープの内容を表示します。 |
dumpheap |
ガベージ コレクトされたヒープと、オブジェクトの収集統計に関する情報を表示します。 |
dumpil |
マネージド メソッドに関連付けられている共通中間言語 (CIL) を表示します。 |
dumplog |
メモリ内ストレス ログの内容を、指定したファイルに書き込みます。 |
dumpmd |
指定されたアドレスにある 構造体に関する情報を表示します。 |
dumpmodule |
指定されたアドレスにあるモジュールに関する情報を表示します。 |
dumpmt |
指定されたアドレスにあるメソッド テーブルに関する情報を表示します。 |
dumpobj |
指定されたアドレスにあるオブジェクトに関する情報を表示します。 |
dumpruntimetypes |
GC ヒープ内のすべての System.RuntimeType オブジェクトを検索し、それらが参照する型名と MethodTable を出力します。 |
dumpsig |
で指定されたメソッドまたはフィールドのシグネチャをダンプします。 |
dumpsigelem |
シグネチャ オブジェクトの 1 つの要素をダンプします。 |
dumpstackobjects |
現在のスタックの範囲内で見つかったすべてのマネージド オブジェクトを表示します。 |
dumpvc |
値クラスのフィールドに関する情報を表示します。 |
eeheap |
内部のランタイム データ構造体によって消費されたプロセス メモリに関する情報を表示します。 |
eestack |
プロセス内のすべてのスレッドに対して を実行します。 |
eeversion |
ランタイムと SOS のバージョンに関する情報を表示します。 |
ehinfo |
JIT されたメソッドの例外処理ブロックを表示します。 |
| または | 対話モードを終了します。 |
finalizequeue |
完了の目的で登録されているすべてのオブジェクトを表示します。 |
findappdomain |
GC オブジェクトの AppDomain の解決を試みます。 |
gchandles |
プロセス内のガベージ コレクター ハンドルに関する統計を表示します。 |
gcheapstat |
ガベージ コレクターに関する統計情報を表示します。 |
gcinfo |
メソッドの JIT GC エンコードを表示します。 |
gcroot |
指定されたアドレスにあるオブジェクトへの参照 (またはルート) に関する情報を表示します。 |
gcwhere |
指定されたアドレスの GC ヒープ内の場所を表示します。 |
histclear |
Hist コマンドのファミリによって使用されているすべてのリソースを解放します。 |
histinit |
デバッグ対象に保存されているストレス ログから SOS 構造体を初期化します。 |
histobj |
すべてのストレス ログ再配置レコードを調べて、引数として渡されたアドレスになった可能性のあるガベージ コレクション再配置のチェーンを表示します。 |
histobjfind |
指定されたアドレスにあるオブジェクトを参照するすべてのログ エントリを表示します。 |
histroot |
指定したルートの上位変換と再配置の両方に関係する情報を表示します。 |
histstats |
ストレス ログの統計を表示します。 |
ip2md |
JIT コンパイルされたコード内の指定したアドレスにある 構造体を表示します。 |
listnearobj |
指定されたアドレスの前および後にあるオブジェクトを表示します。 |
logopen |
コンソール ファイル ログを有効にします。 |
logclose |
コンソール ファイル ログを無効にします。 |
logging |
内部 SOS ログを有効/無効にします。 |
| または | プロセス内のネイティブ モジュールを表示します。 |
name2ee |
指定されたモジュール内の指定の型またはメソッドの および 構造体を表示します。 |
objsize |
指定したオブジェクトのサイズを表示します。 |
parallelstacks |
Visual Studioの [並列スタック] パネルと同様に、マージされたスレッド スタックを表示します。 |
pathto |
から への GC パスを表示します。 |
| または | 指定したアドレスにある クラスから派生したすべてのオブジェクトのフィールドが表示および書式設定されます。 |
| または | スレッドのレジスタを表示します。 |
runtimes |
ターゲット内のランタイムを一覧表示するか、既定のランタイムを変更します。 |
setclrpath |
を使用して coreclr dac/dbi ファイルを読み込むためのパスを設定します。 |
setsymbolserver |
シンボル サーバーのサポートを有効にします。 |
sos |
さまざまな coreclr デバッグ コマンドを実行します。 構文 を使用します。 詳細については、「soshelp」を参照してください。 |
| または | 使用可能なコマンドをすべて表示します。 |
| または | 指定したコマンドを表示します。 |
syncblk |
SyncBlock の所有者の情報を表示します。 |
taskstate |
タスクの状態を人間が判読できる形式で表示します。 |
threadpool |
ランタイム スレッド プールに関する情報を表示します。 |
threadpoolqueue |
キューに登録されたスレッド プールの作業項目を表示します。 |
threadstate |
Pretty はスレッド状態の意味を出力します。 |
| または | SOS コマンドの現在のスレッド ID を設定するか表示します。 |
timerinfo |
実行タイマーに関する情報を表示します。 |
token2ee |
指定されたトークンとモジュールの MethodTable 構造体と MethodDesc 構造体を表示します。 |
traverseheap |
ヒープ情報を、CLR プロファイラーが解釈できる形式でファイルに書き込みます。 |
verifyheap |
破損の兆候がないか GC ヒープを確認します。 |
verifyobj |
引数として渡されたオブジェクトで破損の兆候を調べます。 |
注意
その他の詳細については、SOS Debugging Extension for .NETを参照してください。
dotnet-dump ps
ダンプを収集できる dotnet プロセスを一覧表示します。 バージョン 6.0.320703 以降のバージョンでは、各プロセスが開始されたコマンド ライン引数 (該当する場合) も表示されます。
構文
dotnet-dump ps [-h|--help]
例
コマンド を使用して、実行時間の長いアプリを起動するとします。 別のウィンドウで コマンドを実行します。 表示される出力は次のとおりです。 コマンドライン引数 (ある場合) は、 バージョン 6.0.320703 以降で表示されます。
> dotnet-dump ps
21932 dotnet C:\Program Files\dotnet\dotnet.exe run --configuration Release
36656 dotnet C:\Program Files\dotnet\dotnet.exe
を使用する
まずはダンプを収集します。 コア ダンプを既に生成している場合、この手順をスキップできます。 オペレーティング システムまたは .NET Core ランタイムの組み込みの dump 生成機能は、それぞれコア ダンプを作成できます。
$ dotnet-dump collect --process-id 1902
Writing minidump to file ./core_20190226_135837
Written 98983936 bytes (24166 pages) to core file
Complete
ここで、次のように コマンドを使用して、コア ダンプを分析します。
$ dotnet-dump analyze ./core_20190226_135850
Loading core dump: ./core_20190226_135850
Ready to process analysis commands. Type 'help' to list available commands or 'help [command]' to get detailed help on a command.
Type 'quit' or 'exit' to exit the session.
>
この操作により、次のようなコマンドを受け取る対話型セッションが開始されます。
> clrstack
OS Thread Id: 0x573d (0)
Child SP IP Call Site
00007FFD28B42C58 00007fb22c1a8ed9 [HelperMethodFrame_PROTECTOBJ: 00007ffd28b42c58] System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
00007FFD28B42DD0 00007FB1B1334F67 System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo) [/root/coreclr/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs @ 472]
00007FFD28B42E20 00007FB1B18D33ED SymbolTestApp.Program.Foo4(System.String) [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 54]
00007FFD28B42ED0 00007FB1B18D2FC4 SymbolTestApp.Program.Foo2(Int32, System.String) [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 29]
00007FFD28B42F00 00007FB1B18D2F5A SymbolTestApp.Program.Foo1(Int32, System.String) [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 24]
00007FFD28B42F30 00007FB1B18D168E SymbolTestApp.Program.Main(System.String[]) [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 19]
00007FFD28B43210 00007fb22aa9cedf [GCFrame: 00007ffd28b43210]
00007FFD28B43610 00007fb22aa9cedf [GCFrame: 00007ffd28b43610]
アプリを強制終了させた未処理の例外を表示するには、次のようにします。
> pe -lines
Exception object: 00007fb18c038590
Exception type: System.Reflection.TargetInvocationException
Message: Exception has been thrown by the target of an invocation.
InnerException: System.Exception, Use !PrintException 00007FB18C038368 to see more.
StackTrace (generated):
SP IP Function
00007FFD28B42DD0 0000000000000000 System.Private.CoreLib.dll!System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
00007FFD28B42DD0 00007FB1B1334F67 System.Private.CoreLib.dll!System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)+0xa7 [/root/coreclr/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs @ 472]
00007FFD28B42E20 00007FB1B18D33ED SymbolTestApp.dll!SymbolTestApp.Program.Foo4(System.String)+0x15d [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 54]
00007FFD28B42ED0 00007FB1B18D2FC4 SymbolTestApp.dll!SymbolTestApp.Program.Foo2(Int32, System.String)+0x34 [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 29]
00007FFD28B42F00 00007FB1B18D2F5A SymbolTestApp.dll!SymbolTestApp.Program.Foo1(Int32, System.String)+0x3a [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 24]
00007FFD28B42F30 00007FB1B18D168E SymbolTestApp.dll!SymbolTestApp.Program.Main(System.String[])+0x6e [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 19]
StackTraceString: <none>
HResult: 80131604
メモリ リークと割り当てを分析する
メモリ リークは、不要になったオブジェクトへの参照をアプリが保持し、ガベージ コレクターがメモリを再利用できないようにするときに発生します。 を使用して、メモリ リークを特定し、最大のオブジェクトを見つけ、メモリが消費されている場所を理解します。
メモリ リークのデバッグの完全なチュートリアルについては、「
最大のオブジェクトを識別する
オプションを指定して コマンドを使用して、ヒープ上のオブジェクトの概要を合計サイズで並べ替えて表示します。
> dumpheap -stat
Statistics:
MT Count TotalSize Class Name
00007f6c1eeefba8 576 59904 System.Reflection.RuntimeMethodInfo
00007f6c1dc021c8 1749 95696 System.SByte[]
00000000008c9db0 3847 116080 Free
00007f6c1e784a18 175 128640 System.Char[]
00007f6c1dbf5510 217 133504 System.Object[]
00007f6c1dc014c0 467 416464 System.Byte[]
00007f6c21625038 6 4063376 testwebapi.Controllers.Customer[]
00007f6c20a67498 200000 4800000 testwebapi.Controllers.Customer
00007f6c1dc00f90 206770 19494060 System.String
Total 428516 objects
この出力は、どの型が最も多くのメモリを消費するかを示しています。 この例では、 オブジェクトは約 19 MB、 オブジェクトは約 4.8 MB を消費します。
名前空間またはアセンブリでオブジェクトを識別する
メモリを消費しているモジュールまたは名前空間を見つけるには、 オプションと部分型名を使用して結果をフィルター処理します。
> dumpheap -type MyCompany.Data -stat
Statistics:
MT Count TotalSize Class Name
00007f6c21625038 15000 3600000 MyCompany.Data.CustomerRecord
00007f6c21625040 8000 2560000 MyCompany.Data.OrderHistory
00007f6c21625048 2000 960000 MyCompany.Data.ProductCache
Total 25000 objects, 7120000 bytes
この方法は、コードベースのどの部分がメモリ消費を担当するかを識別するのに役立ちます。
インスタンス化の最大数を検索する
インスタンスが最も多い型を確認するには、合計サイズに関係なく、出力の Count 列を確認します。 インスタンス数が多いオブジェクトは、非効率的なオブジェクトの作成またはキャッシュの問題を示している可能性があります。
> dumpheap -stat
Statistics:
MT Count TotalSize Class Name
00007f6c1dc00f90 206770 19494060 System.String
00007f6c20a67498 200000 4800000 testwebapi.Controllers.Customer
00007f6c1dc021c8 1749 95696 System.SByte[]
この例では、206,770 インスタンスと 200,000 インスタンスを示します。
gcroot を使用してオブジェクト参照を分析する
大きいオブジェクトまたは多数のオブジェクトを識別した後、 を使用して、オブジェクトがガベージ コレクションされていない理由を確認します。 コマンドは、GC ルートから特定のオブジェクトへの参照チェーンを示します。
> dumpheap -mt 00007f6c20a67498
Address MT Size
00007f6ad09421f8 00007f6c20a67498 24
...
> gcroot 00007f6ad09421f8
Thread 3f68:
00007F6795BB58A0 00007F6C1D7D0745 testwebapi.Controllers.CustomerCache.GetAll()
rbx: (interior)
-> 00007F6BDFFFF038 System.Object[]
-> 00007F69D0033570 testwebapi.Controllers.Processor
-> 00007F69D0033588 testwebapi.Controllers.CustomerCache
-> 00007F69D00335A0 System.Collections.Generic.List`1[[testwebapi.Controllers.Customer]]
-> 00007F6C000148A0 testwebapi.Controllers.Customer[]
-> 00007F6AD0942258 testwebapi.Controllers.Customer
Found 1 root.
この出力は、 オブジェクトが オブジェクトによって保持されていることを示しています。これは、コード内のリークの原因を特定するのに役立ちます。
オブジェクト サイズ別にメモリを分析する
オプションとオプションを使用して、サイズでオブジェクトをフィルター処理します。
> dumpheap -min 100000 -stat
Statistics:
MT Count TotalSize Class Name
00007f6c21625038 6 4063376 testwebapi.Controllers.Customer[]
00007f6c1dc014c0 12 416464 System.Byte[]
Total 18 objects
このコマンドは、100,000 バイトを超えるオブジェクトのみを表示し、最大のメモリ コンシューマーに集中するのに役立ちます。
デッドロックの検出
を使用して、スレッドがリソースの待機中にブロックされるデッドロックの状況を診断します。 デッドロックデバッグの完全なチュートリアルについては、「debug a deadlock in .NET」を参照してください。
すべてのスレッドを一覧表示する
コマンドを使用して、すべてのマネージド スレッドを表示します。
> threads
*0 0x1DBFF (121855)
1 0x1DC01 (121857)
2 0x1DC02 (121858)
...
スレッド スタックを調べる
を使用して、すべてのスレッドの呼び出し履歴を確認します。
> clrstack -all
または同様の同期プリミティブで複数のスレッドがブロックされているパターンを探します。
ロック所有者の検索
コマンドを使用して、ロックを保持しているスレッドと待機しているスレッドを確認します。
> syncblk
Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner
43 00000246E51268B8 603 1 0000024B713F4E30 5634 28 00000249654b14c0 System.Object
44 00000246E5126908 3 1 0000024B713F47E0 51d4 29 00000249654b14d8 System.Object
MonitorHeld 列には、ロックを待機しているスレッドの数が表示されます。 [ 所有スレッド情報] 列には、ロックを所有しているスレッドが表示されます。
高度なメモリ分析シナリオ
複数のダンプを比較する
時間の経過に伴うメモリの増加を理解するには、複数のダンプを収集して比較します。
- ベースライン ダンプを収集します。
- アプリを実行させ、より多くのメモリを消費します。
- 2 番目のダンプを収集します。
- 両方のダンプを分析し、 結果を比較します。
2 番目のダンプで、インスタンス数が大幅に多い型または合計サイズが大きい型を探します。
特定のオブジェクトの種類のメモリを分析する
特定の型のすべてのインスタンスをダンプするには:
> dumpheap -type Customer
Address MT Size
00007f6ad09421f8 00007f6c20a67498 24
00007f6ad0942210 00007f6c20a67498 24
...
次に、 を使用して個々のオブジェクトを調べます。
> dumpobj 00007f6ad09421f8
Name: testwebapi.Controllers.Customer
MethodTable: 00007f6c20a67498
EEClass: 00007f6c21625000
Size: 24(0x18) bytes
File: /app/testwebapi.dll
Fields:
MT Field Offset Type VT Attr Value Name
00007f6c1dc00f90 4000001 8 System.String 0 instance 00007f6ad09421f0 Name
00007f6c1dbf4c18 4000002 10 System.Int32 1 instance 42 Id
ダンプ収集に関する問題の解決
ダンプ収集では、プロセスで を呼び出せることが必要になります。 ダンプを収集できない場合、そのような呼び出しを制限するように環境が構成されている可能性があります。 一般的な問題の解決ヒントと考えられる解決策については、「ダンプ: FAQ」を参照してください。
関連項目
- メモリ ダンプの収集と分析に関するブログ
- ヒープ分析ツール (dotnet-gcdump)
.NET