知識マップ: .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でメモリが下がっても根本原因は消えておらず、本番へ入れる対策にはならない。

.NETのGC待ちとメモリリークの見分け方の知識マップ.NETでメモリ増加がGC待ちか本当のメモリリークかを、dotnet-counters・dotnet-gcdump・dotnet-dumpとgcrootで切り分ける関係を示す図で確認できるで確認できるで確認できるで確認できるで確認できるで確認できるで確認できる用いるのは非推奨用いるのは非推奨用いるのは非推奨原因になり得る原因になり得る原因になり得る原因になり得る原因になり得る原因になり得る原因になり得るより先に行うべきより先に行うべき両立しない両立しない利用する前提とする.NETのガベージコレクション(GC).NETのメモリリーク(意図しない保持)dotnet-countersdotnet-gcdumpdotnet-dumpgcrootコマンドGCヒープ(マネージドヒープ)dumpheap -statコマンドdotnet-traceGen 2(第2世代ヒープ)Total Allocated(累積割り当て量)Working Set / RSS強制GC(Induced Collection)staticコレクションによる保持上限・期限のないキャッシュイベント購読解除漏れTimerの破棄漏れIDisposableの解放漏れDIライフタイムの取り違えLOH(Large Object Heap).NET Framework.NET(Core以降)

概念間の関係(全23件)

図と同じ関係を文章でも列挙します。表示している文と機械可読な意味データ(RDFa)は同じ要素に載っています。確度が「確立した関係」のものは直接の関係として、「条件付きの関係」のものは成立条件つきの言明(rdf:Statement)として表現しています。

主要概念の定義

.NETのガベージコレクション(GC)
オブジェクトへ到達できる参照が無くなったときに.NETランタイムがそのメモリを回収する仕組み。割り当て状況やヒープのしきい値、世代を見ながら動く。
.NETのメモリリーク(意図しない保持)
業務上は不要になったオブジェクトが、staticフィールド・キャッシュ・イベント・Timer・DIのライフタイムなどから参照され続け、GCが回収できずに増え続ける状態。
GCヒープ(マネージドヒープ)
GCの回収対象となるマネージドオブジェクトが置かれるヒープ領域。dumpheapで見えるのはこの範囲だけで、ネイティブ側のメモリは含まれない。
Total Allocated(累積割り当て量)
起動後にアプリが割り当てたメモリの累積量を表す指標。GCで回収されても値は減らない。
Working Set / RSS
物理メモリ上に載っているプロセスのページ量を表すOS視点のメモリ指標。GCヒープの生存オブジェクト量とは一致しない。
強制GC(Induced Collection)
アプリケーションコードが明示的に要求するガベージコレクション。未回収だったオブジェクトをその場で回収するだけで、根本原因を消すものではない。
staticコレクションによる保持
staticフィールドのコレクションへ追加し続け、プロセスが生きている限りオブジェクトを保持し続けてしまうリークパターン。
上限・期限のないキャッシュ
最大件数や有効期限を設けていないキャッシュで、実質的にメモリリークとして働く状態。
イベント購読解除漏れ
寿命の長いpublisherが寿命の短いsubscriberをイベントハンドラー経由で参照し続け、購読解除しない限りsubscriberが解放されないリークパターン。
Timerの破棄漏れ
System.Threading.TimerなどのTimerを破棄しないまま残し、コールバックのdelegateを通じてオブジェクトを保持し続けるリークパターン。
IDisposableの解放漏れ
using/await usingなどで所有権を明確にせず、ファイル・ソケット・ハンドルなどのリソースが解放されないまま残る状態。
DIライフタイムの取り違え
寿命の長いsingletonサービスがリクエスト単位のデータを保持してしまい、リクエストが終わってもオブジェクトが残ってしまう設計上の誤り。
LOH(Large Object Heap)
85,000バイト以上の大きなオブジェクトが置かれる特別なヒープ。
dotnet-counters
実行中の.NETプロセスのGCやWorking Setなどの傾向をリアルタイムに監視する診断ツール。
dotnet-gcdump
実行中の.NETプロセスからGC dumpを取得し、型ごとのCount/Sizeの統計を比較するための診断ツール。
dotnet-dump
プロセスのダンプ(ヒープダンプやクラッシュダンプ)を収集・解析する.NETの診断ツール。SOSコマンド(dumpheap・gcroot・clrstackなど)でヒープの参照元やスタックトレースを調べられるが、ネイティブのスタックフレームは扱えない。

機械可読データ

このページはサイトの知識グラフ(_data/knowledge/)から自動生成されています。誤りの指摘はお問い合わせからお願いします。