AWS EC2(Linux)上の .NET 8 マイクロサービスでメモリリークを疑い、dotnet-dump でダンプを取得したのに「Heap Information: Not Present」と表示されて解析が進まない――。この症状は、ツールの世代差や解析環境の前提違いが重なると発生しやすい典型例です。原因の切り分けポイントと、現場で使える具体的な対応手順をまとめます。
「Heap Information: Not Present」が意味すること
ダンプを開いたときに表示される 「Heap Information: Not Present」 は、ざっくり言うと「(解析ツールが期待する)ヒープ情報ストリームが入っていない/読めない」状態を示します。ここで注意したいのは、ヒープといっても文脈が2種類ある点です。
- ネイティブヒープ(OS/ランタイム外も含む、一般的なヒープ)
- .NET マネージヒープ(GCが管理するオブジェクト領域)
メモリリーク調査で本当に見たいのは、多くの場合「どの型のオブジェクトが残り続けているか」「何がルートになっているか」といった .NET マネージヒープの情報です。しかし、取得したダンプの種類・ツールのバージョン・解析環境が噛み合わないと、ダンプは取れているのにマネージヒープ解析が成立しないことがあります。
最初に確認すべき結論:dotnet6-dump で .NET 8 を調べるのは危険
提示されているコマンドは次の形です。
dotnet6-dump collect --type heap --process-id 2083
ここが最大の落とし穴になりやすいです。「dotnet6-dump」=.NET 6 世代のツール(または古いdotnet-dumpを別名で使っている)である可能性が高く、.NET 8 のプロセスに対しては互換性問題や既知不具合に当たりやすいです。
重要なのはコマンド名ではなく、内部で動いている dotnet-dump の実バージョンです。まずは現場で、次を必ず実行して「何が入っているのか」を確定させます。
dotnet-dump のバージョン確認
dotnet-dump --version
# もしくは
dotnet-dump -h
もし「dotnet6-dump」しか存在しない/それを使っている場合でも、実体が dotnet-dump の古いビルドであることが多いです。グローバルツールで入れているなら、次で一覧も確認できます。
dotnet tool list -g
よくある原因は大きく3系統
| 原因の系統 | 起きやすい状況 | 症状の例 | 優先度 |
|---|---|---|---|
| ツールが古い(世代不一致/既知不具合) | .NET 8 を dotnet6-dump 等で取得 | ダンプは取れるが Heap 情報が欠落、VSでマネージ解析が機能しない | 最優先 |
| 解析環境の前提違い(LinuxダンプをWindowsのVSで…) | Linux上で採取→Windowsへ持ち込み | 開けても機能が限定、期待するメモリビューが出ない | 高 |
| 権限/セキュリティ/実行形態の制約 | 非root、systemd、コンテナ、ptrace制限 | 採取失敗、途中で中身が薄い、必要領域が取れない | 中 |
今回の「Heap Information: Not Present」は、特に「ツールが古い」+「WindowsのVisual Studioで解析しようとしている」の組み合わせで発生しやすい典型パターンです。
対応手順:dotnet-dump を最新化して heap 付きダンプを取り直す
まずは採取側(EC2/Linux)で dotnet-dump を更新し、同じプロセスに対して再取得して症状が消えるかを確認します。ここで解消するケースが非常に多いです。
グローバルツールの更新(推奨)
dotnet tool update -g dotnet-dump
未インストールなら install です。
dotnet tool install -g dotnet-dump
インストール後、パスが通っていないと実行できません。一般的には ~/.dotnet/tools を PATH に含めます(Linuxのシェルにより設定方法は異なります)。
更新後のバージョン確認
dotnet-dump --version
ポイントは「.NET 8 と同世代以上の dotnet-dump を使う」ことです。古い世代の dotnet-dump には、heap 付きで採取したつもりでも必要な情報が欠ける不具合・互換性問題が報告されていることがあります。質問のように「Heap Information: Not Present」になってしまう場合、まずここを疑うのが最短ルートです。
heap 付きで再取得(出力ファイル名も明示)
sudo dotnet-dump collect --type heap --process-id 2083 --output /tmp/service_2083_heap.dmp
※ sudo が必要かどうかは、対象プロセスの実行ユーザーと採取ユーザー次第です。同一ユーザーで実行できるなら sudo を避けた方が運用上は安全です(権限を絞れるため)。
「heap」以外も使い分ける
メモリリーク調査では heap が第一候補ですが、状況により他タイプも有効です。
| 採取タイプ | 主な用途 | メリット | 注意点 |
|---|---|---|---|
| heap | マネージヒープ中心の解析(リーク調査の定番) | フルより軽く、オブジェクト分布や参照関係を追いやすい | ネイティブ側の詳細は追えないことがある |
| full | 原因が不明で、ネイティブ/マネージ混在の疑いが強い | 材料が多く、後から「足りない」が起きにくい | サイズが大きい・採取負荷が高い・機密情報も増える |
| triage / mini(環境により呼称差) | 障害時に最小限で状況把握したい | 採取が速く運用しやすい | メモリ解析には情報不足になりがち |
「heap で足りない」または「heap がどうしても薄い」場合は、短時間だけでも full を1本採って材料を確保する判断が有効です(もちろん本番影響と機密リスクを評価した上で)。
Windows の Visual Studio 2022 でうまく解析できない理由と現実的な回避策
質問には「Windows 環境の Visual Studio 2022 で解析したい」という要望がありますが、ここにOSの壁があります。
Linuxで採取したダンプは、基本的にLinux前提で解析する
Linux上で採取したダンプ(コアダンプ/createdump系)は、Linuxのデバッガや .NET 診断ツールでの解析が基本です。WindowsのVisual Studioは便利ですが、“Windowsで採ったWindowsダンプ” を前提にした機能が多く、Linuxダンプを開けたとしても、期待する「マネージメモリ解析UI」が十分に動かないケースがあります。
現場でのおすすめ構成:解析は WSL / Linux、可視化は gcdump を Windows へ
実務で強いのは次の分業です。
- 詳細な低レベル解析(スタック、GCルート、参照追跡):WSL2 または Linux 上で
dotnet-dump analyze - マネージヒープの可視化(どの型が多いか、世代別傾向):
dotnet-gcdumpを採取して Windows の Visual Studio / PerfView で確認
「Windowsだけで完結したい」気持ちはよく分かりますが、Linux採取→Windows解析は制限が出やすいため、最短で前進させるならこの分業が安定します。
Linux(またはWSL)で dotnet-dump analyze を使う具体例
ダンプが取れたら、同じくLinux側(EC2)またはWSLで解析します。WSLを選ぶと「Windows端末のままLinux解析」ができるので、運用的に採用しやすいです。
基本の流れ
# WSL または Linux 環境で
dotnet tool install -g dotnet-dump # 未導入なら
dotnet-dump analyze /path/to/service_2083_heap.dmp
解析シェルに入ったら、まずは全体像をつかみます(コマンド名は環境や拡張の有無で差が出ることがあります)。
# 例:読み込み/拡張の確認
sos
# 例:マネージスタック(スレッドの実行状況)
clrstack
# 例:マネージヒープ統計(型別の個数・サイズ)
dumpheap -stat
# 例:特定の型のインスタンス一覧(アドレス列挙)
dumpheap -type Namespace.TypeName
# 例:なぜ回収されないか(GCルート探索)
gcroot
ここで「dumpheap -stat が動かない」「SOSがロードできない」といった場合、ダンプが薄い可能性もありますが、ツール更新で改善するケースも多いです。まずは採取側ツールの世代を疑い、採り直しを優先してください。
代替・補完策:dotnet-gcdump でマネージヒープを確実に“見える化”する
メモリリーク調査では「どの型が増え続けているか」を早く掴むことが重要です。その目的に限るなら、dotnet-gcdump は非常に強力です。
dotnet-gcdump の導入と採取
dotnet tool install -g dotnet-gcdump # 未導入なら
dotnet-gcdump collect -p 2083 -o /tmp/service_2083.gcdump
.gcdump は「GCの観点で見たマネージヒープのスナップショット」に近く、Windowsにコピーして Visual Studio 2022 や PerfView で可視化できます。LinuxのフルダンプをWindowsで無理に扱うより、最初から“Windowsで見やすい形式”を別途採るのが現実的です。
dotnet-dump と dotnet-gcdump の使い分け
| 観点 | dotnet-dump(heap/full) | dotnet-gcdump |
|---|---|---|
| 狙い | 原因特定まで深掘り(GCルート/参照追跡/スレッド含む) | 増えている型・傾向を素早く可視化 |
| 取得コスト | 中〜高(fullは特に高) | 比較的低い |
| Windowsとの相性 | Linux採取だと制限が出やすい | 良い(VS/PerfViewで扱いやすい) |
| 向いている場面 | 「なぜ残るか」まで追う、ネイティブ混在も疑う | 「何が増えているか」をまず掴む、継続監視にも |
おすすめは、gcdump で方向性を決めてから dump で確定調査に入る流れです。これにより「重いフルダンプを闇雲に増やす」ことを避けられます。
それでも Heap 情報が入らないときのチェックリスト(EC2/Linux)
ツール更新後も症状が続く場合に備えて、現場で確認しやすい順に並べます。
| チェック項目 | 確認コマンド例 | NGだと起きること | 対処の方向性 |
|---|---|---|---|
| 対象プロセスの .NET バージョン/アーキテクチャ | dotnet --info / ps -p 2083 -o comm= | x64端末でARM64ダンプを解析しようとして詰まる等 | 同一アーキテクチャの環境で解析(GravitonならARM64前提) |
| 採取ユーザーと対象プロセスの権限関係 | ps -o user,pid,cmd -p 2083 | 採取に失敗、または内容が限定される | 同一ユーザーで実行、必要ならsudo |
| ptrace制限(セキュリティ設定) | cat /proc/sys/kernel/yama/ptrace_scope | 診断アタッチが拒否される/不安定 | 運用ポリシーの範囲で緩和、または同一ユーザー運用へ |
| ディスク容量(/tmp や出力先) | df -h | 途中で書けず不完全なダンプになる | 十分な容量のパスへ出力、S3退避運用 |
| 本番影響(一時停止/CPU負荷) | 監視(ALB/アプリログ/メトリクス) | 採取中にタイムアウトが増える | 低トラフィック時に実施、事前に手順を短縮 |
特にAWS Graviton(ARM64)で動かしている場合、「Windows x64 の開発端末で解析しようとして詰まる」ことが現実に起こります。ダンプは採取した環境のCPUアーキテクチャの影響を強く受けるため、解析環境も同系統に揃える(ARM64ならARM64、x64ならx64)意識が重要です。
メモリリーク調査を前に進める“実務的”おすすめ手順
「Heap Information: Not Present」で足踏みしないために、最短で効果が出やすい手順をテンプレ化しておくのがおすすめです。
ステップ1:採取ツールの世代を揃える
- EC2側で
dotnet-dump --versionを確認 dotnet tool update -g dotnet-dumpで更新- 可能なら .NET 8 と同世代以上のツールに統一
ステップ2:まず gcdump を1本(傾向把握)
dotnet-gcdump collectで.gcdumpを採取- Windowsへコピーして VS/PerfView で「増えている型」を特定
ステップ3:原因確定が必要なら heap dump / full dump
- 増えている型の候補が分かったら
dotnet-dump collect --type heap - それでも追えない、ネイティブ混在が疑わしいなら
--type fullを検討 - 解析は WSL/Linux の
dotnet-dump analyzeを基本線にする
本番運用で忘れがちな注意点(セキュリティと再現性)
ダンプはトラブルシュートに強い一方、運用上の事故も起こしやすいデータです。公開用の記事として、ここは明確に押さえておくと評価が上がります。
ダンプには機密情報が含まれ得る
- アクセストークン、接続文字列、個人情報、リクエスト内容などがメモリ上に残る可能性があります。
- S3へ退避する場合は、暗号化(KMS)と期限付き削除の運用をセットで設計してください。
「同じ条件で再現できる」情報も一緒に残す
- 採取時刻、対象PID、アプリのバージョン(Git SHA等)、.NETランタイムバージョン
- インスタンスタイプ(x64/arm64)、OSディストリ、カーネル情報
- 直前の負荷状況(リクエスト数、キュー長、GCカウンタ)
これらが残っていると、後から「なぜこのダンプは薄いのか」「別環境で解析できないのはなぜか」を短時間で説明できます。
まとめ:この症状は“ツール更新”と“解析方法の切り替え”で解消しやすい
- dotnet6-dump のような古い世代のツールで .NET 8 を扱うと、heap 付きのつもりでも情報が欠けることがあります。
- まず dotnet-dump のバージョン確認→最新化を実施し、heap dump を採り直すのが最短です。
- Linuxで採取したダンプをWindowsのVisual Studioで完全解析するのは制限が出やすいため、WSL/Linuxでdotnet-dump analyzeを基本にするのが現実的です。
- 可視化とスピード重視なら dotnet-gcdump(.gcdump)を併用し、VS/PerfViewで「増えている型」を先に掴むと調査が一気に進みます。

コメント