次の方法で共有


ダンプの収集と分析のユーティリティ (dotnet-dump)

この記事の対象: ✔️ バージョン 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) を分析できますが、これはネイティブのデバッガーではないため、ネイティブ スタック フレームの表示などの操作はサポートされていません。

オプション

  • --version

    dotnet-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

メモリ リークと割り当てを分析する

メモリ リークは、不要になったオブジェクトへの参照をアプリが保持し、ガベージ コレクターがメモリを再利用できないようにするときに発生します。 を使用して、メモリ リークを特定し、最大のオブジェクトを見つけ、メモリが消費されている場所を理解します。

メモリ リークのデバッグの完全なチュートリアルについては、「.NETを参照してください。

最大のオブジェクトを識別する

オプションを指定して コマンドを使用して、ヒープ上のオブジェクトの概要を合計サイズで並べ替えて表示します。

> 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 列には、ロックを待機しているスレッドの数が表示されます。 [ 所有スレッド情報] 列には、ロックを所有しているスレッドが表示されます。

高度なメモリ分析シナリオ

複数のダンプを比較する

時間の経過に伴うメモリの増加を理解するには、複数のダンプを収集して比較します。

  1. ベースライン ダンプを収集します。
  2. アプリを実行させ、より多くのメモリを消費します。
  3. 2 番目のダンプを収集します。
  4. 両方のダンプを分析し、 結果を比較します。

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)