知識マップ: .NETでGC待ちとメモリリークを見分ける ── 増えるメモリを観測・比較・証明する実務手順
記事「.NETでGC待ちとメモリリークを見分ける ── 増えるメモリを観測・比較・証明する実務手順」の主張を、概念と関係(エッジ)に分解した知識グラフの全体です。各関係には根拠・確認日・確度が付いています。
.NETアプリのメモリ増加は、ガベージコレクションがまだ回収していないだけの場合と、staticコレクションや上限のないキャッシュ、イベント購読解除漏れ、Timerの破棄漏れ、IDisposableの解放漏れ、DIライフタイムの取り違えなどにより本当に参照が残り続けている場合とに分かれる。見分けにはまずdotnet-countersでGCヒープやGen 2、LOHの傾向を確認し、累積値であるTotal AllocatedやOS視点のWorking Setの増加だけでは判断しないことが重要になる。次にdotnet-gcdumpで負荷前後の型ごとのCountとSizeを比較して増えている型を特定し、dotnet-dumpのdumpheapとgcrootコマンドで誰がそのオブジェクトを参照し続けているのかまで追う。強制GCでメモリが下がっても根本原因は消えておらず、本番へ入れる対策にはならない。
flowchart LR
accTitle: .NETのGC待ちとメモリリークの見分け方の知識マップ
accDescr: .NETでメモリ増加がGC待ちか本当のメモリリークかを、dotnet-counters・dotnet-gcdump・dotnet-dumpとgcrootで切り分ける関係を示す図
dotnet_garbage_collection[".NETのガベージコレクション(GC)"]
dotnet_memory_leak[".NETのメモリリーク(意図しない保持)"]
dotnet_counters["dotnet-counters"]
dotnet_gcdump["dotnet-gcdump"]
dotnet_dump["dotnet-dump"]
gcroot_command["gcrootコマンド"]
gc_heap["GCヒープ(マネージドヒープ)"]
dumpheap_command["dumpheap -statコマンド"]
dotnet_trace["dotnet-trace"]
gen2_heap["Gen 2(第2世代ヒープ)"]
total_allocated_memory["Total Allocated(累積割り当て量)"]
working_set_rss["Working Set / RSS"]
induced_gc["強制GC(Induced Collection)"]
static_collection_leak["staticコレクションによる保持"]
unbounded_cache["上限・期限のないキャッシュ"]
event_subscription_leak["イベント購読解除漏れ"]
timer_disposal_leak["Timerの破棄漏れ"]
idisposable_leak["IDisposableの解放漏れ"]
di_lifetime_mismatch["DIライフタイムの取り違え"]
large_object_heap["LOH(Large Object Heap)"]
dotnet_framework[".NET Framework"]
dotnet[".NET(Core以降)"]
dotnet_garbage_collection -->|"で確認できる"| dotnet_counters
dotnet_memory_leak -->|"で確認できる"| dotnet_gcdump
dotnet_memory_leak -->|"で確認できる"| dotnet_dump
dotnet_memory_leak -->|"で確認できる"| gcroot_command
gc_heap -->|"で確認できる"| dumpheap_command
dotnet_memory_leak -.->|"で確認できる"| dotnet_trace
dotnet_memory_leak -->|"で確認できる"| gen2_heap
total_allocated_memory -->|"用いるのは非推奨"| dotnet_memory_leak
working_set_rss -->|"用いるのは非推奨"| dotnet_memory_leak
induced_gc -->|"用いるのは非推奨"| dotnet_memory_leak
static_collection_leak -.->|"原因になり得る"| dotnet_memory_leak
unbounded_cache -.->|"原因になり得る"| dotnet_memory_leak
event_subscription_leak -.->|"原因になり得る"| dotnet_memory_leak
timer_disposal_leak -.->|"原因になり得る"| dotnet_memory_leak
idisposable_leak -.->|"原因になり得る"| dotnet_memory_leak
di_lifetime_mismatch -.->|"原因になり得る"| dotnet_memory_leak
large_object_heap -.->|"原因になり得る"| dotnet_memory_leak
dotnet_counters -->|"より先に行うべき"| dotnet_gcdump
dotnet_gcdump -->|"より先に行うべき"| dotnet_dump
dotnet_counters -->|"両立しない"| dotnet_framework
dotnet_dump -->|"両立しない"| dotnet_framework
dotnet_garbage_collection -->|"利用する"| gc_heap
dotnet_garbage_collection -->|"前提とする"| dotnet
概念間の関係(全23件)
図と同じ関係を文章でも列挙します。表示している文と機械可読な意味データ(RDFa)は同じ要素に載っています。確度が「確立した関係」のものは直接の関係として、「条件付きの関係」のものは成立条件つきの言明(rdf:Statement)として表現しています。
- .NETのガベージコレクション(GC)はdotnet-countersで確認できます。
- .NETのメモリリーク(意図しない保持)はdotnet-gcdumpで確認できます。
- .NETのメモリリーク(意図しない保持)はdotnet-dumpで確認できます。
- .NETのメモリリーク(意図しない保持)はgcrootコマンドで確認できます。
- GCヒープ(マネージドヒープ)はdumpheap -statコマンドで確認できます。
- .NETのメモリリーク(意図しない保持)はdotnet-traceで確認できます。
- .NETのメモリリーク(意図しない保持)はGen 2(第2世代ヒープ)で確認できます。
- Total Allocated(累積割り当て量)を.NETのメモリリーク(意図しない保持)に用いることは推奨されません。
- Working Set / RSSを.NETのメモリリーク(意図しない保持)に用いることは推奨されません。
- 強制GC(Induced Collection)を.NETのメモリリーク(意図しない保持)に用いることは推奨されません。
- staticコレクションによる保持は.NETのメモリリーク(意図しない保持)の原因になることがあります。
- 上限・期限のないキャッシュは.NETのメモリリーク(意図しない保持)の原因になることがあります。
- イベント購読解除漏れは.NETのメモリリーク(意図しない保持)の原因になることがあります。
- Timerの破棄漏れは.NETのメモリリーク(意図しない保持)の原因になることがあります。
- IDisposableの解放漏れは.NETのメモリリーク(意図しない保持)の原因になることがあります。
- DIライフタイムの取り違えは.NETのメモリリーク(意図しない保持)の原因になることがあります。
- LOH(Large Object Heap)は.NETのメモリリーク(意図しない保持)の原因になることがあります。
- dotnet-countersはdotnet-gcdumpより先に行うべきです。
- dotnet-gcdumpはdotnet-dumpより先に行うべきです。
- dotnet-countersは.NET Frameworkと両立しません。
- dotnet-dumpは.NET Frameworkと両立しません。
- .NETのガベージコレクション(GC)はGCヒープ(マネージドヒープ)を利用します。
- .NETのガベージコレクション(GC)は.NET(Core以降)を前提とします。
主要概念の定義
機械可読データ
このページはサイトの知識グラフ(_data/knowledge/)から自動生成されています。誤りの指摘はお問い合わせからお願いします。