topは、サーバーの状態をリアルタイムに監視するコマンドです。free・uptimeが「その瞬間の数値」を一度だけ表示するのに対し、topは数秒ごとに自動更新しながら、CPU・メモリの使用状況と、動いているプロセスの一覧を表示し続けます。「サーバーが重い」というとき、何が原因なのかを突き止めるための最初の一手です。
topは情報量が多く、初めて見ると圧倒されます。しかし見るべき場所は決まっています。この記事では、実機のLinuxで実際に負荷をかけて数値が動く様子を確認し、さらに稼働中の本番サーバーの実データも使いながら、topの読み方と、スクリプトで使える-b(バッチモード)を整理します。
topで起動、qで終了。数秒ごとに自動更新されます。- 上部にload average・Tasks・%Cpu・メモリ、下部にプロセス一覧が表示されます。
%Cpu(s)のid(アイドル)を見れば、CPUに余裕があるか一目で分かります。top -b -n 1で1回だけ出力でき、スクリプトやログ保存に使えます。-o %CPUや-o %MEMで、重いプロセスを並べ替えて特定できます。- load averageが高くてもCPUがアイドルなこともあります(I/O待ちなど)。
数値を一度だけ見るならfree・uptime、プロセスの終了はps・kill、ディスクはdu・dfもあわせて参考になります。
topの画面構成
topを実行すると、画面が上部の「サマリー領域」と下部の「プロセス一覧」に分かれます。まずは上部の5行の意味を押さえましょう。
top # 起動(q キーで終了) # top - 10:23:02 up 0 min, 0 users, load average: 0.00, 0.00, 0.00 # ↑現在時刻 ↑稼働時間 ↑1分/5分/15分の平均負荷 # Tasks: 7 total, 1 running, 6 sleeping, 0 stopped, 0 zombie # ↑プロセス数の内訳(running=実行中、zombie=ゾンビ) # %Cpu(s): 4.1 us, 0.0 sy, 0.0 ni, 95.9 id, 0.0 wa, ... # ↑CPU使用率の内訳(後述) # MiB Mem : 31683.6 total, 31010.2 free, 408.9 used, 264.6 buff/cache # MiB Swap: 8192.0 total, 8192.0 free, 0.0 used. 30975.0 avail Mem # ↑メモリとスワップ(free コマンドと同じ内容) # PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND # ↑ここから下がプロセス一覧(既定はCPU使用率順)
実機でtopを実行すると、1行目に時刻・稼働時間・load average、2行目にプロセス数の内訳(running=実行中、zombie=終了処理が済んでいないゾンビプロセス)、3行目にCPU使用率、4〜5行目にメモリとスワップが表示されました。メモリの内容はfreeコマンドと同じで、avail Mem(=available)が実質的に使えるメモリです。そして下部にプロセス一覧が、既定ではCPU使用率の高い順に並びます。
【重要】%Cpu(s)行の読み方
topで最も重要なのが%Cpu(s)行です。CPUの時間が何に使われているかの内訳を示します。特にid(アイドル)とwa(I/O待ち)が重要です。
%Cpu(s): 4.1 us, 0.0 sy, 0.0 ni, 95.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st # us (user) … ユーザープログラムの処理(アプリの計算など) # sy (system) … カーネルの処理(システムコールなど) # ni (nice) … 優先度を変更したプロセスの処理 # id (idle) … 何もしていない=空き(★これが大きいと余裕あり) # wa (iowait) … ディスクI/O待ち(★大きいとディスクがボトルネック) # hi/si … ハードウェア/ソフトウェア割り込み # st (steal) … 仮想化環境でホストに奪われた時間(VPSで重要)
見るべき優先順位はこうです。まずid(アイドル)——これが大きければCPUに余裕があります。次にwa(I/O待ち)——これが大きい場合、CPUではなくディスクがボトルネックです(ディスク容量や遅いストレージが原因のことも)。usが高いのはアプリが計算している状態で、syが異常に高い場合はシステムコールの多発を疑います。VPSなど仮想環境ではst(steal)も要注目で、これが高いと「同居する他の利用者にCPUを奪われている」ことを意味します。
【実証】負荷をかけると数値が動く
実際にCPU負荷をかけて、topの数値がどう変わるかを確認しました。数値が実際に動く様子を知っておくと、本番で異常を見抜きやすくなります。
# 負荷なしの状態 %Cpu(s): 0.0 us, 0.4 sy, 0.0 ni, 99.6 id, ... # ↑ほぼ100%アイドル # CPUを使い続けるプロセスを4つ起動してから… %Cpu(s): 25.1 us, 0.0 sy, 0.0 ni, 74.5 id, ... # ↑us が 25% に上昇(16コア中4コア分=25%) # プロセス一覧(CPU使用率順) # PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND # 32 root 20 0 6828 3332 3072 R 100.0 0.0 0:04.29 bash # 33 root 20 0 6828 3216 2956 R 100.0 0.0 0:04.30 bash # 34 root 20 0 6828 3248 2988 R 100.0 0.0 0:04.30 bash # 36 root 20 0 6828 3212 2952 R 100.0 0.0 0:04.30 bash # ↑負荷をかけた4プロセスが %CPU 100.0 で上位に並ぶ
実機(16コア)で、CPUを使い続けるプロセスを4つ起動してtopの変化を測定しました。負荷前は99.6 id(ほぼ完全にアイドル)でしたが、負荷をかけると25.1 us/74.5 idへ変化しました。16コアのうち4コア分を使い切ったので、ちょうど25%という計算が合います。さらにプロセス一覧を見ると、負荷をかけた4つのbashプロセスが%CPU 100.0で上位に並びました。ここで注意したいのが%CPUは「1コアを100%とした値」だということです。そのためマルチコア環境では100%を超える値(200%、400%など)も表示されます——これは異常ではなく「複数コアを使っている」という意味です。「%Cpu(s)行=サーバー全体の割合」「プロセスの%CPU=1コア基準」という違いを理解しておくと、数値を正しく読めます。
【実例】load averageが高くてもCPUはアイドル
load averageと%Cpuは別物です。実際に稼働している本番サーバーのデータが、その違いをよく表していました。
top - 10:23:30 up 8 days, 6:49, 0 users, load average: 59.59, 66.26, 63.48 # ↑ 59.59! 高そうに見える Tasks: 4 total, 1 running, 3 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.9 id, 0.0 wa, ... # ↑ でも 99.9% アイドル(CPUは暇) MiB Mem : 1547455.+total, 1517980.+free, 16940.4 used, 12535.2 buff/cache # ↑ 約1.5TB のメモリ # このサーバーは 256 コア → load 59.59 は約23%で余裕 # しかも自分から見える範囲のCPUはほぼアイドル
実際に稼働している本番サーバー(共用レンタルサーバー)でtopを実行したところ、load average: 59.59という一見驚くような数値でした。ところが同じ画面の%Cpu(s)は99.9 id(99.9%アイドル)——CPUはほとんど何もしていないのです。この一見矛盾する状態には理由があります。まずこのサーバーは256コアなので、load 59.59は全体の約23%にすぎません。加えて、load averageは「CPU実行待ち」だけでなく「ディスクI/O待ち」のプロセスも含むため、CPUが暇でもI/Oが混んでいれば数値が上がります。さらに共用サーバーでは、自分のシェルから見えるプロセスは限られる(Tasks: 4 total)のに対し、load averageはサーバー全体の状態を示します。「load averageが高い=CPUが忙しい」とは限らない——この点を理解しておくと、原因の切り分けを誤りません。CPUが原因かは%Cpu(s)のidとwaで判断してください。
-bバッチモードでスクリプトに使う
topは対話的な画面ですが、-b(バッチモード)を使うと1回だけ結果を出力して終了できます。cronでの定期記録や、ログ保存に最適です。
# -b: バッチモード, -n 1: 1回だけ更新して終了 top -b -n 1 # CPU使用率の高い順に上位10件だけ記録 top -b -n 1 -o %CPU | head -17 > /var/log/top_snapshot.log # メモリ使用率順に並べる top -b -n 1 -o %MEM | head -12 # 特定ユーザーのプロセスだけ top -b -n 1 -u www-data # 特定のPIDだけ監視 top -b -n 1 -p 1234 # cron で定期記録する例(毎時0分) # 0 * * * * top -b -n 1 >> /var/log/top_hourly.log
実機でも、top -b -n 1で対話画面を開かずに1回分の情報を出力でき、-o %CPUでCPU使用率順、-o %MEMでメモリ使用率順に並べ替えられることを確認しました。-u ユーザー名で特定ユーザーのプロセスだけ、-p PIDで特定のプロセスだけに絞ることもできます。-bを使えばリダイレクトでファイルに保存でき、cronで定期的にサーバー状態を記録できます。「深夜に負荷が上がる」といった調査では、この定期記録が原因究明の決め手になります。
対話画面での主なキー操作
topを対話的に使うときの覚えておくべきキーをまとめます。最低限q(終了)だけ知っていれば困りません。
| キー | 働き |
|---|---|
q |
topを終了する(最重要) |
M |
メモリ使用率順に並べ替え |
P |
CPU使用率順に並べ替え(既定) |
k |
プロセスを終了(PIDを入力) |
1 |
CPUコアごとの使用率を表示 |
h |
ヘルプを表示 |
特に1(数字のイチ)は便利で、CPUコアごとの使用率を個別に表示できます。「全体では50%だが、1つのコアだけ100%で他は暇」といった並列化されていない処理を見つけられます。重いプロセスを見つけたらkで終了できますが、killコマンドを使うほうが確実です。
よくある失敗
topから抜けられない
qキーで終了できます。Ctrl+Cでも止まります。
プロセスの%CPUが100%超で驚く
%CPUは1コア基準です。マルチコアでは100%超も正常です。
load averageが高い=CPU過負荷と判断する
I/O待ちも含まれます。%Cpu(s)のidとwaで切り分けます。
スクリプトでtopを使おうとして固まる
対話画面のままです。-b -n 1でバッチモードにします。
waが高いのにCPUを増やそうとする
waが高いのはディスクがボトルネックです。ストレージ側を見直します。
よくある質問
qキーを押せば終了します。Ctrl+Cでも止められます。topは数秒ごとに自動更新し続ける対話画面なので、見終わったらqで抜けてください。スクリプトで使いたい場合は、対話画面を開かずに1回だけ出力するtop -b -n 1(バッチモード)を使います。id(アイドル=空き)を見ます。これが大きければCPUに余裕があります。次にwa(I/O待ち)で、これが大きいとCPUではなくディスクがボトルネックです。usはアプリの処理、syはカーネルの処理、VPSなどではst(ホストに奪われた時間)も重要です。%CPUは「1コアを100%」とした値だからです。マルチコア環境で複数コアを使うプロセスは、200%や400%といった値になります。異常ではありません。一方、上部の%Cpu(s)行はサーバー全体を100%とした割合なので、意味が異なります。実機でも、負荷をかけた各プロセスが100.0%と表示されることを確認しています。%Cpu(s)は99.9%アイドルという状態を確認しています。加えてそのサーバーは256コアなので、load 59.59は全体の約23%にすぎません。load averageはコア数と比較し、CPUが原因かはidとwaで判断してください。top -b -n 1 > ファイル名とします。-bがバッチモード(非対話)、-n 1が1回だけ更新の指定です。-o %CPUでCPU順、-o %MEMでメモリ順に並べ替えられます。cronで定期実行すれば、負荷が上がる時間帯の調査に使えます。まとめ
topでリアルタイム監視、qで終了。%Cpu(s)のid(空き)とwa(I/O待ち)が最重要です。- プロセスの
%CPUは1コア基準なので100%超も正常です。 top -b -n 1でスクリプト・cron記録に使えます。- load averageが高くてもCPUがアイドルなことがあります(I/O待ち・コア数)。
topは、サーバーの「今」を映し出す監視ツールの定番です。「idとwaを見る」「%CPUは1コア基準」「スクリプトなら-b」——この3点を押さえれば、重いプロセスの特定とボトルネックの切り分けが的確にできます。free・uptimeで全体像を掴み、topで犯人を特定し、killで対処する——この流れがサーバートラブル対応の基本形です。
- grep(文字列検索)
- find(ファイル検索)
- sed(置換・行編集)
- awk(列抽出・集計)
- cut(列の切り出し)
- chmod(パーミッション)
- tar(圧縮・解凍)
- gzip・gunzip(ファイル圧縮)
- リダイレクトとパイプ
- echo・printf(文字列出力)
- ps・kill(プロセス管理)
- free・uptime(メモリ/負荷)
- top(リアルタイム監視)
- 環境変数とPATH
- which・type(コマンドの正体)
- ln(シンボリックリンク)
- cp・mv・rm(コピー/移動/削除)
- touch・mkdir(ファイル/フォルダ作成)
- basename・dirname(パス分解)
- history(コマンド履歴)
- curl(HTTP通信・API)
- wget(ダウンロード)
- ping(疎通確認)
- dig・nslookup(DNS調査)
- ss・netstat(ポート確認)
- jq(JSON処理)
- vim(基本操作・終了方法)
- cron・crontab(定期実行)
- test・[ ](条件判定)
- read(入力の読み取り)
- date(日付・時刻)
- sort・uniq・wc(並べ替え/集計)
- xargs(一括処理)
- chown・chgrp(所有者/グループ変更)
- diff(ファイル比較)
- du・df(ディスク使用量)
- head・tail(先頭/末尾・ログ監視)
- cat・less(ファイル表示)
- alias(コマンドの別名)
- nohup(SSH切断対策)
- tmux(セッション管理)
- よく使うコマンドまとめ
- cd(ディレクトリ移動)
