LinuxのCPU使用率が高い原因と対処法|実践的なトラブルシューティングを徹底解説

はじめに

商用システムの運用では、LinuxサーバのCPU使用率が急上昇するトラブルは珍しくありません。CPU負荷は一時的なスパイクで終わることもあれば、アプリケーションのレスポンス遅延やタイムアウト、バッチ処理の遅延、さらにはサービス停止へ発展することもあります。

重要なのは、CPU使用率が高いという事実だけを見て原因を決めつけないことです。まずシステム全体の状態を確認し、CPU時間の内訳を見て、どのProcess・ThreadがCPUを使用しているのかを段階的に絞り込んでいきます。

本記事では、LinuxサーバにおけるCPU高負荷を検知してから、原因を特定し、暫定対処・恒久対処へつなげるまでの流れを実践的に解説します。まず全体フローを確認し、実際の状況に応じて必要な章から読み進めても問題ありません。

CPU高負荷とは

CPU使用率は、一定時間のうちCPUがどのような処理に時間を使っていたかを示す指標です。CPU使用率が高いこと自体が、直ちに障害を意味するわけではありません。高いCPU使用率でも処理性能やレスポンスが要求を満たしている場合は、必ずしも問題ではありません。

一方で、高負荷状態が継続しCPUの余力がなくなると、次のような影響が発生する可能性があります。

  • アプリケーションのレスポンス遅延・タイムアウト
  • バッチ処理の遅延・タイムアウト
  • SSHや運用コマンドの応答悪化
  • Run Queueの増加による処理待ち
  • 他Processへの性能影響
ポイント:CPU使用率だけではなく、Load Average、CPU時間の内訳、Run Queue、Process単位のCPU使用率などを組み合わせて判断します。

CPU高負荷のトラブルシューティング全体像

CPU高負荷を検知したら、いきなり原因Processを探すのではなく、次の順番で調査すると効率よく切り分けできます。

特に商用システムでは、障害発生中に調査できるとは限りません。現在の状態を見るコマンドと、過去の状態を振り返るコマンドを使い分けることが重要です。

状況主なコマンド用途
現在発生中top / vmstat / pidstatリアルタイムに状況を確認
発生後の事後調査sar障害発生時刻のCPU状態を振り返る

CPU全体の状態を確認する

topで現在のCPU状態を確認する

障害が現在進行中であれば、まずtopでシステム全体を確認します。

# top

実際のtop実行例:

CPU調査では、主に次の2点を確認します。

  • Load Average
  • %Cpu(s) の内訳

Load Averageを確認する

Load Averageは、過去1分・5分・15分におけるシステム負荷の平均値です。Linuxでは、CPUを実行中または実行待ちのTaskだけでなく、割り込み不可スリープ(D state)にあるTaskもLoad Averageに含まれます。

重要:Load Averageが高い = CPU使用率が高いとは限りません。

たとえば、Load Averageが高いにもかかわらずCPUのidleが十分に残っている場合は、CPU不足ではなく、Block I/O待ちなどでD stateのTaskが増えていないか確認する必要があります。

CPU論理コア数はnprocやlscpuで確認できます。

また、top実行中に「1」を押すと、CPUコアごとの使用状況を確認できます。

CPU全体の使用率には余裕があっても、Single Thread処理やCPU Affinityなどの影響で、特定の論理CPUだけが100%近く使用されている場合があります。そのため、CPU全体の平均値だけでなく、CPUコアごとの偏りも確認します。

CPUコアごとの表示例:

CPU時間の内訳を確認する

topの%Cpu(s)には、CPUがどの種類の処理に時間を使っていたかが表示されます。

項目意味高い場合に疑うもの
usUser Modeで通常Processを実行した時間Application処理、計算処理、SQL処理など
syKernel Modeで処理した時間System Call、Kernel処理など
ninice値が変更されたUser Processの実行時間nice設定されたProcess
idCPUがidleだった時間値が小さいほどCPUの余力が少ない
waI/O完了待ちに関連してidleとして計上された時間Block I/Oの遅延を疑う。ただし単独で断定しない
hiHardware Interrupt処理時間Device / Interrupt負荷
siSoftIRQ処理時間Network受信などのSoftIRQ負荷
stVirtual MachineがHypervisor側の都合でCPUを使えなかった時間Host側CPU競合・Overcommitなど

idがほぼ0でCPU使用率が高い場合でも、まずus、sy、si、stなどのどこが増えているかを見ます。原因によって次に調査する対象が変わるためです。

vmstatでRun Queueも確認する

vmstatを使うと、CPUだけでなくMemoryやI/Oを横断的に確認できます。

# vmstat 1

vmstatの実行結果:

CPU高負荷時は、特にr、us、sy、id、waを確認します。

項目見るポイント
r実行可能状態のTask数。継続的に論理CPU数を大きく上回る場合はCPU待ちを疑う
usUser ModeのCPU時間
syKernel ModeのCPU時間
ididle時間
waI/O待ちに関連する時間。I/O Bottleneckの手掛かりとして確認

sarで障害発生時のCPU状態を振り返る

商用システムでは、「22時頃にCPUアラートが発生したが、現在は正常」というケースがよくあります。この場合、現在のtopを確認しても障害発生時の状況は分かりません。

sysstatが有効化されていれば、sarを使って過去のCPU状態を確認できます。

sar -u

実際の sar -u の実行結果:

過去の日付のsysstatファイルを指定する場合は、環境に応じて次のように確認します。

sar -u -f /var/log/sa/sa0X

実際の sar -u -f の実行結果:

CPUコアごとに確認したい場合は次のように実行します。

sar -P ALL

実際の sar -P ALL の実行結果:

sarでは、障害発生時刻の%user、%system、%iowait、%steal、%idleなどを確認し、「CPUの何が上昇していたのか」を切り分けます。

実務ポイント:監視アラートの発生時刻と、sar・Application Log・Batch実行時刻などを突き合わせると、原因を特定しやすくなります。

CPU時間の内訳から原因を切り分ける

観測結果疑う対象次の調査例
usが高いApplication / DBなどのUser Processtop、pidstatでProcess特定
syが高いSystem Call / Kernel処理pidstat、必要に応じてperfなど
waが高いBlock I/O遅延の可能性iostat -xなどでI/O状態を確認
siが高いSoftIRQ負荷/proc/softirqs、Network負荷などを確認
stが高いVirtualization Host側のCPU競合Hypervisor / Cloud側のMetricsを確認

CPUを使用しているProcessを特定する

topでCPU使用率の高いProcessを確認する

topでは、ProcessごとのCPU使用率をリアルタイムに確認できます。CPUを多く消費しているProcessを特定し、Application名や実行ユーザー、起動コマンドなどを確認します。

Process一覧では、特にPID、USER、PR、NI、S、%CPU、TIME+、COMMANDを確認します。

マルチスレッドProcessでは、1つのProcessの%CPUが100%を超えることがあります。たとえば4論理CPUをフルに使用するProcessでは、約400%と表示されることがあります。

pidstatでProcessのCPU使用率を時系列で確認する

pidstatを使うと、Process単位のCPU使用率を一定間隔で確認できます。

pidstat 1

実際の pidstat の実行結果:

特定Processだけに絞る場合は-pを指定します。

pidstat -p 707126 1

%usr、%system、%wait、%CPUを見ることで、そのProcessがどのようにCPUを消費しているかを確認できます。

psでCPU使用率の高いProcessを一覧化する

コマンド実行時点のProcess一覧をCPU使用率順に取得したい場合は、psも便利です。

ps aux --sort=-%cpu | head

実際の ps aux の実行結果:

Thread単位まで原因を深掘りする

Java ApplicationやマルチスレッドProgramでは、Process単位でCPU使用率が高いことが分かっても、どの処理が原因なのかまでは分かりません。その場合はThread単位まで掘り下げます。

top -HでThreadを確認する

top -H -p <PID>

実際の top -H の表示例:

対象Processに属するThreadごとのCPU使用率が表示されます。

pidstat -tでThreadを確認する

pidstat -t -p <PID> 1

実際のThread単位のpidstat実行結果:

TID(Thread ID)単位でCPU使用率を確認し、特にCPUを消費しているThreadを特定します。

(補足)Java Applicationの場合

TomcatなどのJava Applicationでは、次のように調査を進めると原因を絞り込みやすくなります。

  1. top / pidstat
  2. Java Processが高CPU
  3. top -H / pidstat -t
  4. 高CPU Threadを特定
  5. Thread Dumpなどと照合
  6. Applicationの処理を特定

CPU使用率の高いThreadを特定した後は、Thread DumpやApplication固有のProfiling情報などを用いて、どの処理がCPUを消費しているのかを確認します。

Application / OS / DBまで原因を追う

ProcessやThreadを特定したら、そのProcessがなぜCPUを使用しているのかを調査します。この段階では、OS全体のMetricsだけでなく、ApplicationやMiddleware、Database側の情報が重要になります。

OS / Kernel Log

RHEL系では、環境に応じてjournalctlや/var/log/messagesを確認します。

# journalctl -k
# journalctl --since "2026-09-09 05:00" --until "2026-09-09 06:00"
# tail /var/log/messages

Soft Lockup、Hard Lockup、Taskの長時間Blockなど、CPU高負荷と関連するKernel Messageがないかを確認します。

Web / AP Server

ApacheやNginxではAccess Logを確認し、CPU高負荷が発生した時間帯にRequest数が急増していないか、特定URLへ集中していないかを確認します。

TomcatなどのJava Applicationでは、Application Logに加えてGC Logも確認します。GC回数やGC時間が通常時より大きく増えている場合は、GC負荷がCPU使用率上昇に関係している可能性があります。

GC Logの例:

Database

Database ProcessがCPUを大量に使用している場合は、SQLやSessionの状態をDatabase側で確認します。

PostgreSQLではSlow Query Logやpg_stat_activity、pg_stat_statementsなど、Oracle DatabaseではAWRやASHなどを利用し、CPU消費の大きいSQLや処理を特定します。

PostgreSQL Slow Query Logの例:

必要に応じてperfなどで深掘りする

topやpidstatでは「どのProcess / ThreadがCPUを使っているか」は確認できますが、「どのFunctionやCode PathでCPU時間を消費しているか」までは分かりません。

より深い分析が必要な場合は、perfなどのProfiling Toolを使ってCPU Hotspotを調査します。

# perf top
# perf record -p <PID> -g -- sleep 30
# perf report
perfは、取得するEvent、Sampling Frequency、Call Graphの取得方法などの条件によって追加負荷が発生します。本番環境で利用する場合は、事前検証のうえ取得条件や実行時間を調整してください。

CPU高負荷時の暫定対処

以下では、実際にCPU高負荷状態を再現して取得した画面・コマンド結果も使いながら説明します。

原因調査と並行してサービス影響が拡大している場合は、システムを安定させるための暫定対処を検討します。ただし、原因を十分に確認せずにProcess停止やCPU制限を行うと、別の障害を引き起こす可能性があります。

Service / Processを停止する

原因Serviceが特定でき、停止しても業務影響を許容できる場合は、Serviceとして管理されているProcessであればsystemctl stopなどの正規の停止手順を優先します。

systemctl stop <service>

個別ProcessにSignalを送る場合、通常はまずSIGTERMで正常終了を要求します。

kill <PID>

SIGTERMによる停止例:

SIGTERMで停止できず、影響を確認したうえで緊急停止が必要な場合に限り、SIGKILLを最終手段として検討します。

kill -9 <PID>

SIGKILLの実行例:

注意:SIGKILLではProcessがCleanup処理を実行できません。Databaseや重要Middlewareでは、製品固有の停止手順を優先し、安易にkill -9を実行しないでください。

優先度を下げる

停止できないProcessについて、他Processへの影響を抑えるためにnice値を変更する方法があります。

renice 10 -p <PID>

renice の実行例:

ただし、nice値を下げてもCPU負荷そのものが解消するわけではありません。あくまでCPU競合時のScheduling優先度を調整する対処です。

CPU使用量を制御する

Service単位でCPU使用量を制御する必要がある場合は、まずsystemdやcgroupsによるCPU Resource Controlを検討します。商用システムでは、Service管理方式や運用標準に合わせて制御方法を選択することが重要です。

cpulimitを利用して個別ProcessのCPU使用率を制限する方法もありますが、systemdやcgroupsで管理できない場合の補足的な選択肢として考えます。

cpulimit -p <PID> -l <使用率制限値> &

cpulimit の実行例:

上記の例では、PID 887537のProcessのCPU使用率を50%に制限し、cpulimitをBackgroundで実行しています。

CPUリソースを増強する

Virtual MachineやCloud環境では、vCPUを追加することで一時的に余力を確保できる場合があります。

ただし、Single Thread処理、Lock競合、I/O待ち、Application設計が原因の場合は、CPU数を増やしても改善しないことがあります。CPU増強は原因を切り分けたうえで実施します。

CPU高負荷の恒久対処

恒久対処では、CPU使用率が上昇した根本原因を解消します。代表的な対処は次の通りです。

  • Applicationの改善:無限Loop、高負荷な計算処理、無駄なPollingなどを修正する
  • SQLの最適化:CPU消費の大きいSQLを見直し、IndexやSQLを改善する
  • Batch設計の改善:実行時間帯の変更、分割、並列度の調整を行う
  • Traffic制御:Rate Limitや流量制御を導入し、突発的なRequest増加に備える
  • Capacity見直し:CPU数、Instance Size、Scale Out構成などを見直す
  • 監視強化:CPU使用率だけでなくLoad Average、Run Queue、Process単位のCPU、Application Metricsを継続監視する

まとめ

LinuxサーバでCPU使用率が上昇した場合、重要なのはCPU使用率という1つのMetricだけを見て原因を決めつけないことです。

  1. まずCPU全体を見る:top、sar、vmstatで現在または障害発生時の状態を確認する。
  2. CPU時間の内訳を見る:us、sy、wa、si、stなどから調査対象を切り分ける。
  3. Processを特定する:top、pidstat、psを利用する。
  4. Threadまで深掘りする:top -Hやpidstat -tで高負荷Threadを特定する。
  5. 根本原因まで追う:Application Log、GC、Database、必要に応じてperfなどで原因を分析する。
  6. 暫定対処と恒久対処を分ける:Service停止、優先度調整、Resource制御などで影響を抑えつつApplication・SQL・Capacityなどの根本原因を改善する。

CPU調査はシステム全体 → CPU時間の内訳 → Process → Thread → Applicationの順に段階的に絞り込むことが重要です。

参考資料

※コマンド出力やLog保存先はDistribution、Version、設定により異なります。実環境の設計・運用ルールに合わせて確認してください。

現場で使えるLinuxトラブルシューティング

Linuxのトラブルシューティングを図解で学びたい方へ

障害の切り分けから詳細解析まで、図解を中心に初心者にも分かりやすく解説しています。


Kindleで書籍を見る

コメント