top と htop 徹底活用 - ボトルネックを見抜く
この記事で解決できること
topのサマリ行から CPU・メモリ・I/O どこが詰まっているか を 30 秒で判断できる%us%sy%wa%siの 意味と切り分け基準 が分かるhtopのツリー表示・フィルタ・F キー操作で 対話的に犯人プロセスを追える- 「load average が高い」だけで終わらせず、根本原因の層まで掘れる
結論(30 秒診断の型)
topの 3 行目を見る →%us高なら CPU バウンド、%wa高なら I/O 待ち、%sy高ならカーネル/コンテキストスイッチtopの 4 行目を見る →freeが極小かつswap used増加中ならメモリ不足- 犯人特定は
htopでツリー表示 + ソート(P / M / T キー)
前提(対象環境)
- OS:Ubuntu / RHEL 系 Linux
htopは標準では未インストールの場合あり(sudo apt install htop/sudo dnf install htop)- 本記事の表示は procps-ng の
topを前提(BSD 系topは表示が異なる)
なぜ top と htop を使い分けるのか?
top は どの環境にも必ずある(procps-ng 由来でほぼ全 Linux に同梱)。一方 htop は 対話性とビジュアル に優れ、ツリー表示・カラー・マウス操作・複数列ソートを備える。前者は障害現場の最終防衛線、後者は日常の調査効率化、と役割が違う。
使い分けの基準
- 緊急時 / 最小環境 / SSH のみ →
top(バイナリ存在を期待できる) - 日常監視 / 子プロセス含む解析 / 複数プロセス一括 kill →
htop
top の画面はどう読むのか?
top 起動直後に表示される 5 行のサマリが最重要。プロセス一覧は二の次。
top - 14:32:11 up 12 days, 3:45, 2 users, load average: 4.21, 3.85, 2.10
Tasks: 234 total, 2 running, 232 sleeping, 0 stopped, 0 zombie
%Cpu(s): 12.3 us, 3.2 sy, 0.0 ni, 78.5 id, 5.8 wa, 0.0 hi, 0.2 si, 0.0 st
MiB Mem : 16004.0 total, 412.5 free, 12890.3 used, 2701.2 buff/cache
MiB Swap: 2048.0 total, 102.3 free, 1945.7 used, 1893.4 avail Mem
1 行目: uptime + load average
load average: 4.21, 3.85, 2.10 は 過去 1 / 5 / 15 分の実行待ち + R/D 状態のプロセス数の平均。CPU コア数と比較する。
- 例: 4 コア機で
4.21→ ほぼフル稼働 - 例: 4 コア機で
8.50→ 慢性的に過負荷 - 1 分 > 15 分 → 負荷上昇中、1 分 < 15 分 → 沈静化中
load average は R(実行可能)+ D(uninterruptible sleep) を含む。%wa が高い場合 load も上がるため、「load 高 = CPU 不足」とは限らない。
3 行目: CPU 内訳(最も重要)
| 列 | 意味 | 異常基準 |
|---|---|---|
us |
ユーザープロセス CPU 使用率 | 持続的に 80%+ で CPU バウンド |
sy |
カーネル CPU 使用率 | 30%+ なら syscall 過多 |
ni |
nice 値変更されたプロセス | 通常は気にしない |
id |
アイドル | 低いほど忙しい |
wa |
I/O 待ち(ディスク・ネット) | 20%+ なら I/O ボトルネック |
hi |
ハード割込み | 通常 < 1% |
si |
ソフト割込み | 5%+ ならネット/タイマ多発 |
st |
仮想化環境で奪われた時間 | 10%+ なら隣人 VM の影響 |
4-5 行目: メモリと Swap
freeが極小 +buff/cache大 → 健全(カーネルが活用中)freeが極小 +buff/cache小 +swap used増加中 → メモリ不足avail Memは「実際に追加プロセスが使える量」の現実的な指標。freeより参照価値が高い
CPU ボトルネックはどこで判断するのか?
3 行目 %us が 持続的に 80% 以上 で、特定プロセスに集中している状態が CPU バウンド。
切り分け手順
# 1. top で全体把握 $ top # 2. CPU でソート(top 起動中に Shift + P) # プロセス一覧の %CPU 列が降順になる # 3. 単一プロセスが 100%(コア 1 つ分)超え → そのプロセスが原因 # 複数プロセスに分散 → 全体的な過負荷、スケールアウト検討
top の 1 キー: コアごとの内訳に切り替わる。シングルスレッド処理が 1 コア占有しているケースを即座に発見できる。
%us 高だが原因プロセスが見つからない場合
- ユーザープロセスが短命で top の更新間隔(既定 3 秒)に映らない可能性
top -d 0.5で更新を高速化、またはpidstat 1で 1 秒粒度の観測
メモリ不足はどう見抜くのか?
free が小さい = メモリ不足、ではない。Linux は空きメモリをページキャッシュとして活用するため、free は常に小さく見える。
真のメモリ不足の判定基準
MiB Memのavail Memが 総量の 5% 未満MiB Swapのusedが 増加し続けているtop起動中Shift + Mで RES(実メモリ使用)ソート → 単一プロセスが異常に大きいdmesg | grep -i "killed process"で OOM Killer の発動跡を確認
Swap 利用 ≠ 即メモリ不足。低頻度アクセスページが Swap に追い出されるのは正常動作。問題は swap used が 継続的に増え続け、I/O wait(%wa)も同時に上がる 状態(スラッシング)。
I/O 待ちはどう特定するのか?
%wa が 20% 以上で持続する場合、CPU は遊んでいるがディスク/ネット待ちでタスクが進まない状態。
切り分けコマンド
# どのプロセスが D 状態(uninterruptible sleep)か $ ps -eo state,pid,cmd | grep "^D" # ブロックデバイスごとの I/O 量 $ iostat -xz 1 # プロセスごとの I/O(iotop は root 権限必要) $ sudo iotop -o
判定の早見表
| %us | %wa | 状態 |
|---|---|---|
| 高 | 低 | CPU バウンド(演算過多) |
| 低 | 高 | I/O バウンド(ディスク・ネット遅延) |
| 高 | 高 | 混在(DB の重いクエリでありがち) |
| 低 | 低 | ロック待ち・外部 API 待ち・スリープ |
htop の便利機能とは?
htop は top の上位互換に見えるが、特に強力なのは ツリー表示・フィルタ・複数プロセス一括操作。
起動時の表示
0[|||||||||||||||| 45.2%] Tasks: 87, 234 thr; 3 running
1[||||||||| 22.1%] Load average: 1.85 1.42 1.05
2[||||||||||||||||||||||||||||||||||||| 98.7%] Uptime: 12 days, 03:45:11
3[||| 5.3%]
Mem[||||||||||||||||||||| 12.5G/16.0G]
Swp[||||| 1.9G/2.0G]
コアごとの使用率が 棒グラフで一目 で分かる。コア 2 だけが 98.7% → シングルスレッドプロセスがボトルネックという推測が立つ。
よく使う F キー / ショートカット
| キー | 機能 |
|---|---|
F2 |
設定(色・列・表示モード変更) |
F3 / / |
プロセス名でインクリメンタル検索 |
F4 / \ |
プロセス名でフィルタ(一覧を絞り込み) |
F5 / t |
ツリー表示の切替(親子関係を可視化) |
F6 |
ソート列の選択 |
F9 / k |
シグナル送信(SIGTERM / SIGKILL など) |
Space |
プロセスを「タグ付け」(複数選択) |
Shift + P |
CPU % でソート |
Shift + M |
メモリ % でソート |
Shift + T |
起動時間でソート |
u |
ユーザーで絞り込み |
ツリー表示が刺さる場面
└─ nginx: master process
├─ nginx: worker process
├─ nginx: worker process
└─ nginx: cache manager process
F5 のツリー表示は、子プロセスが暴走している親を特定 したいときに最強。worker のうち 1 つだけが CPU 食い → 配信中のリクエスト固有の問題、と分かる。
複数プロセスの一括 kill
/で検索 orF4でフィルタして対象を絞るSpaceで目当てのプロセスに次々タグ付け(複数可)F9でシグナル選択 → 全タグに一括送信
SIGKILL(9)は最後の手段。まず SIGTERM(15)→ 反応なしなら SIGKILL の順を守る。データベースや書き込み中プロセスへの SIGKILL はデータ破損リスクあり。
実践: ボトルネック診断の型
実際の障害対応で使う 3 ステップフロー。
ステップ 1: top のサマリで層を絞る(10 秒)
$ top -b -n 1 | head -5
-b(バッチ)+ -n 1(1 回)でログ収集にも使える。
%wa突出 → I/O 層を疑う(次はiostat)%us突出 → アプリ層を疑う(次はhtopでプロセス特定)%sy突出 → カーネル層を疑う(次はstrace,perf)Swap used増加 → メモリ層を疑う(次はShift + Mソート)
ステップ 2: htop で犯人プロセスを特定(30 秒)
$ htop # Shift + P / M / T で関心軸でソート # F5 でツリー表示にして親子関係を確認
ステップ 3: 根本原因の調査
- アプリ層 →
strace -p PID -f, アプリログ - I/O 層 →
iotop -o,iostat -x 1 - カーネル層 →
dmesg -T,journalctl -k - メモリ層 →
dmesg | grep -i oom, アプリのリーク調査
現場テンプレ: 30 秒トリアージ
# 1. 全体把握 top -b -n 1 | head -20 # 2. load の傾向 uptime # 3. メモリ実状 free -h # 4. I/O 待ち詳細 iostat -xz 1 3 # 5. 犯人特定(対話モード) htop
やってはいけないこと
top / htop でやりがちな失敗
load averageだけ見て「CPU 不足」と即断する(%wa由来かも)freeの値だけ見て「メモリ不足」と即断する(avail Memを見るべき)topの一瞬の値で判断する(最低 10 秒は観察、一過性ピークかを判別)- SIGKILL を最初に使う(プロセスがデータをフラッシュする機会を奪う)
- ツリー表示を無視して親プロセスだけ kill する(孤児プロセス化のリスク)
まとめ
topの 3 行目(CPU 内訳) と 4-5 行目(メモリ) が診断の入口%us/%sy/%waの どれが高いか でボトルネック層を切り分けるhtopの ツリー表示・フィルタ・タグ付け で犯人プロセスを効率特定- 「30 秒トリアージ → 層特定 → 専用ツール(iostat/strace 等)で深堀り」が実務の型