Claude Codeの/heapdumpでメモリ使用量の高さを診断する
/heapdumpはヒープスナップショットと診断用JSONを書き出す隠しコマンドです。メモリ警告の出方、共有してはいけないファイル、サマリーの読み方別の次の一手をまとめます。
メモリ警告が出たら、まず何を試すか
/heapdumpは、Claude Codeのメモリ使用量が高止まりしたときの診断コマンドです。ただ、いきなり使うものではありません。セッションのヒープメモリが2.5GBを超えると、メモリ使用量が危険な水準だという警告が表示されます。警告が出たら、診断より先に軽い対処から順に試します。
メモリが高いときの切り分け順
- 1
/compactで会話を圧縮する
フルスクリーン描画を使っていない環境では、
/compactでもメモリが解放され、使用量が2.5GBを下回れば警告は消えます。Not enough messages to compact.と返るのは、要約できるほどターン数がない状態です。コンテキストが埋まっていても、大きな貼り付けが1回あっただけで起こります。 - 2
再起動して--continueで再開する
Claude Codeを終了し、
claude --continueで会話を新しいプロセスに引き継ぎます。会話は新しいプロセスで再開されます。大きな作業を終えるたびにClaude Codeを再起動する運用も、これも対処の一つです。 - 3
大きなビルドディレクトリを.gitignoreに入れる
大規模なコードベースを扱うと、Claude Codeが使う資源も増えます。生成物のディレクトリを
.gitignoreに追加して、対象から外します。 - 4
--safe-modeで原因の所在を切り分ける
プラグイン・MCPサーバー・Hookのどれかが原因かどうかを見ます。症状が消えたなら、原因はカスタマイズ側にあります。
ここまで試しても高いままなら、/heapdumpの出番です。--safe-modeが「カスタマイズが原因か」を切り分けるのに対し、/heapdumpはメモリの中身そのものを見ます。safe modeの使い方はClaude Code safe modeで「壊れた」設定を1コマンドで切り分けるに詳しく書いています。
--safe-modeで何が無効になるか
v2.1.287のclaude --helpは、--safe-modeを次のように説明します。
$ claude --help
--safe-mode Start with all customizations
(CLAUDE.md, skills, installed plugins,
hooks, MCP servers, custom commands and
agents, output styles, workflows, custom
themes, keybindings, and more) disabled
— useful for troubleshooting a broken
configuration. Admin-managed (policy)
settings still apply. Auth, model
selection, built-in tools and plugins,
and permissions work normally. Sets
CLAUDE_CODE_SAFE_MODE=1.最後の一行のとおり、claude --safe-modeは環境変数CLAUDE_CODE_SAFE_MODE=1を立てます。同じ変数を自分でセットしても、同じ効果になります。起動コマンドを直接変えにくいラッパー経由の環境や、シェルの設定で試したいときに使えます。
一覧に出てくるのは、CLAUDE.md・スキル・プラグイン・Hook・MCPサーバー・出力スタイルなどです。認証、モデル選択、組み込みツール、権限は普通に動きます。つまり、safe modeで軽くなるなら重さの原因は読み込まれていたカスタマイズです。safe modeでも変わらなければ、素の状態でもメモリが増えていることになります。ここで初めて、メモリの中身を見る診断が必要になります。環境変数でメモリまわりの挙動を調整したいときは、Claude Code環境変数リファレンスが手がかりになります。
/heapdumpは何を書き出すか
/heapdumpを実行すると、2つのファイルが~/Desktopに書き出されます。Linuxでデスクトップフォルダーが無い環境では、ホームディレクトリです。
<セッションID>.heapsnapshot: JavaScriptヒープのスナップショット<セッションID>-diagnostics.json: メモリの内訳をまとめた診断用JSON
コマンドメニューには出てきません。/を打って候補を絞っても表示されないため、/heapdumpと最後までタイプして実行します。メニューの仕様として、隠しコマンドは名前の途中までではメニューに現れず、候補が無ければ「該当コマンドなし」と同じ表示になります。全部打ち切ると実行されます。
/heapdump実行すると、会話内にもサマリーが表示されます。プロセス全体のメモリ量、そのうちJSヒープが占める量、ヒープの外にある量が並びます。メモリ増加率が高い、開いているハンドル数が異常に多い、といったリークの兆候があれば、それも一覧に出ます。そしてサマリーは、メモリの大半がスナップショットに映るJSヒープにあるのか、映らないネイティブメモリにあるのかを教えてくれます。この判定が、次の一手を決めます。
.heapsnapshotは公開の場に出さない
2つのファイルのうち、気をつけるのは.heapsnapshotです。プロセス内のすべての文字列が入る形式で、これまでの会話の全文と、環境変数やAPIキーなどの資格情報が含まれます。公開のGitHub Issueに添付したり、チャットに貼ったりする使い方は想定されていません。
2つのファイルの扱い
.heapsnapshot
JSヒープの完全なスナップショットです。会話の全文と資格情報が入っているため、外部には渡せません。Chrome DevToolsで自分で読み込んで調べるためのファイルです。
-diagnostics.json
サマリーの元になった統計情報だけが入っています。会話の内容も資格情報も含みません。GitHub Issueで報告するときは、こちらだけを添付します。
サマリーの結果で、次の一手が分かれる
サマリーに書かれた「大半はどこにあるか」の判定が、調べ方を決めます。
サマリーの判定別の進め方
大半がJSヒープ
.heapsnapshotをChrome DevToolsで開き、保持サイズの大きいオブジェクトから調べます。手順は次の節にあります。大半がネイティブメモリ
スナップショットはJSヒープしか捕捉しないので、DevToolsで開いても原因は見えません。サマリーのリーク兆候を添えて、
-diagnostics.jsonだけを報告します。リーク兆候が出ている
メモリ増加率の高さや、開いているハンドル数の多さが並んでいたら、報告のコメントにそのまま書き写します。
自分で調べる: Chrome DevToolsでスナップショットを開く
サマリーが「JSヒープが大半」と示したときは、.heapsnapshotを自分で読み込めます。
- Chromeで任意のタブを開き、DevToolsを起動する(F12、またはCmd+Option+I)
- Memoryタブを選ぶ
- Loadから
.heapsnapshotファイルを読み込む - Retained Size(そのオブジェクトが解放されたら一緒に解放される量)の降順に並べ替える
上位に並んだオブジェクトの種類から、何がメモリを抱えているかを絞り込めます。
診断用JSONを添えてGitHub Issueで報告する
自分で追いきれないとき、あるいは原因がネイティブメモリ側にあるときは、GitHub Issueを開きます。添付するのは-diagnostics.jsonだけです。サマリーのリーク兆候も、コメントに書き添えます。
# 添付するのは -diagnostics.json のみ
# .heapsnapshot は手元で確認するか削除する
ls ~/Desktop/*-diagnostics.json「重い」の正体がメモリとは限らない場合
「Claude Codeが重い」と感じる原因は、プロセスのメモリだけではありません。/heapdumpの守備範囲外の症状が3つあります。
コンテキストウィンドウの逼迫
コンテキストウィンドウ(会話に読み込まれているトークン量)は、メモリ使用量とは別の指標です。/contextを実行すると、システムプロンプト・システムツール・MCPツール・メモリファイル・スキル・会話メッセージの区分で、何が枠を占めているかを色付きのグリッドで見られます。コンテキストが原因なら、/compactで要約するか、/clearで会話を捨てます。
自動圧縮が成功しても、ファイルやツールの出力が直後に枠を埋め戻すことがあります。これが数回続くと、Autocompact is thrashing: the context refilled to the limit...というエラーで自動圧縮が止まります。対処の1つ目は、大きなファイルを行範囲や関数単位で小さく読ませることです。大きな出力を落とす指示つきの/compactや、大きなファイルを扱う作業のサブエージェントへの移管も、これも対処になります。それでも戻るなら/contextでMessagesの行を他の行と比べます。
大きなMarkdownテーブルの表示
行数が200を超えるMarkdownテーブルは、先頭200行と… N more rows not shownの行で描画されます。制限されるのは表示だけで、会話内には全行が残り、/copyは全行をコピーします。読みにくいだけなら、読むには大きすぎる表は、ファイルに書き出すよう頼めます。v2.1.208より前は全行を描画していたため、巨大な表を含むセッションの再開で再描画が止まることがありました。この症状は表示の問題として扱われています。
バックグラウンドシェルが消える
macOSとLinuxでは、OSが危険なメモリ圧迫を報告し、かつセッションが30分間アイドルのとき、バックグラウンドのシェルコマンドが終了されます。ターン実行中やサブエージェント実行中の場合は対象外です。止めたくないときは、環境変数CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAPを1にします(v2.1.193以降。Windowsにはメモリ圧迫のシグナルがないため効果がありません)。
長い会話でメモリを増やさない設定
重さを事前に抑える設定も用意されています。
フルスクリーン描画は、見えているメッセージだけを描画ツリーに保つため、会話が長くなってもメモリが一定に保たれます。/tui fullscreenで、会話を保ったまま切り替えられます。環境変数CLAUDE_CODE_NO_FLICKER=1でも有効にでき、現状はリサーチプレビューです。
LinuxとWSLでは、CLAUDE_CODE_TOOL_MEMORY_LIMITでBash・PowerShell・Monitorツールのコマンドが使えるメモリの合計を制限できます(v2.1.233以降。Monitorツールはv2.1.246以降)。暴走したビルドが、セッションに必要なメモリまで食うのを防ぐ仕組みです。
# Bash・PowerShell・Monitorツールのコマンド全体で4GBまで
CLAUDE_CODE_TOOL_MEMORY_LIMIT=4G claudeサイズはバイト数か、K・M・G・Tの接尾辞で書きます。0やoffで無効になり、4e9のような書き方は読み取れず無視されます。上限を超えると、カーネルがコマンドを強制終了しますが、結果の中にこの上限のことは出てきません。上限はメモリのcgroupで適用され、セッション内のBash・PowerShell・Monitorのコマンドはすべて1つの上限に合算されます。メモリ制限のcgroupを用意できない環境では、上限なしで動きます。その理由はclaude --debugのログに出ます。値を変えたら、claudeを起動し直すと反映されます。MCP・LSP・Hook・プラグイン・ヘルパーのプロセスをこの上限の対象から外したいときは、環境変数CLAUDE_CODE_TOOL_MEMORY_CGROUP_EXCLUDEを使います(v2.1.246以降)。
並列の作業でも、メモリは増えます。ワークフローは既定で最大16エージェントを同時に走らせ、各エージェントの記録がClaude Codeのメモリに残ります。CLAUDE_CODE_WORKFLOW_MAX_CONCURRENT_AGENTSの値を上げるほど、メモリ使用量も増えます(v2.1.269以降)。
まとめ
警告が出たら、軽い対処を順に試し、それでも高いときに/heapdumpを使います。サマリーがJSヒープを大半と示したなら自分でスナップショットを開き、ネイティブメモリなら診断用JSONだけを報告します。.heapsnapshotは会話の全文を含むので、報告には添えません。
メモリ以外の重さは、コンテキストウィンドウの逼迫・巨大な表の表示・バックグラウンドシェルの終了のどれかです。起動エラー全般はClaude Codeでよくあるエラー10選で調べられます。