Javaアプリケーションがメモリ不足(OOM)で落ちる、もしくはメモリ使用量が異常に増え続ける場合、 jcmd / jmap は最も信頼できる調査ツールです。 本記事では「障害発生時に何から実行すべきか」「出力結果をどう解釈するか」を 実務手順ベースで解説します。
この記事でわかること
本記事を読むことで、Javaプロセスの特定からヒープ使用状況の確認、 ヒープダンプ取得、リークの兆候判定までを一連の流れで理解できます。 また、OOM発生前にやるべき調査と、やってはいけない操作も把握できます。
jcmd / jmap とは何か
jcmdとは
jcmd は JVM に対してコマンドを送信し、状態取得や操作を行う公式ツールです。 jstat や jmap の上位互換的な位置づけで、近年はこちらが推奨されています。
jmapとは
jmap は主にヒープメモリの詳細情報取得に特化したツールで、 ヒープダンプの取得やオブジェクト分布確認に使われます。
【STEP1】Javaプロセスを特定する
まず対象のJavaプロセスID(PID)を特定します。
jps -l
出力例:
12345 com.example.MyApplication
67890 org.apache.catalina.startup.Bootstrap
PID(例:12345)を以降の調査で使用します。
【STEP2】ヒープ使用状況を即座に確認する(最重要)
OOM直前・メモリ高騰時に最優先で実行すべきコマンドです。
jcmd 12345 GC.heap_info
確認ポイント:
- used が max に近づいていないか
- Old Gen が逼迫していないか
この時点で Old領域が常に高止まりしている場合、 メモリリークの可能性が非常に高いと判断できます。
【STEP3】ヒープ全体の利用状況を確認する
jcmd 12345 GC.heap_summary
ここでは以下を見ます。
- Young / Old の比率
- GC後も解放されない領域があるか
GC後も Old Gen が減らない場合は、リークまたはキャッシュ肥大が疑われます。
【STEP4】クラス別オブジェクト数を確認する
どのクラスがメモリを消費しているかを確認します。
jcmd 12345 GC.class_histogram
注目すべきポイント:
- Object 数が異常に多いクラス
- byte サイズが突出しているクラス
例:
num #instances #bytes class name
1: 5000000 400000000 java.lang.String
String や Map 系が多い場合、キャッシュ・セッション保持が原因の可能性があります。
【STEP5】ヒープダンプを取得する(最終手段)
サービス影響を理解した上で、必要な場合のみ実施します。
jcmd 12345 GC.heap_dump /tmp/heapdump.hprof
⚠ 注意点:
- ディスク容量を大量に消費する
- 取得中に一時的な性能低下が発生する
取得後は Eclipse MAT / VisualVM などで解析します。
jmapを使う場合(旧環境・補助用途)
ヒープ使用状況
jmap -heap 12345
ヒストグラム
jmap -histo 12345 | head
ヒープダンプ
jmap -dump:live,format=b,file=/tmp/heap.hprof 12345
※ jmap は STW(Stop The World)が発生しやすいため、 本番では jcmd を優先してください。
よくある失敗パターン
- OOM発生後に実行しても意味がない
- PIDを間違えて別プロセスを調査
- ヒープダンプ取得でディスク枯渇
実務でのおすすめ調査順
- jps でPID特定
- jcmd GC.heap_info
- jcmd GC.class_histogram
- 必要に応じて heap_dump
まとめ
jcmd / jmap は「Javaがなぜメモリで死ぬのか」を可視化する最強ツールです。 特に GC.heap_info → class_histogram の流れは、 OOM原因特定の王道パターンです。




