AWS EC2 Linuxの.NET 8で「Heap Information: Not Present」になる原因とdotnet-dump更新・gcdump解析手順

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で「増えている型」を先に掴むと調査が一気に進みます。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次