perfコマンドでLinuxのCPUホットスポットを特定する方法|perf record・perf reportでボトルネックを調査する実践手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips, Linuxトラブルシューティング > perfコマンドでLinuxのCPUホットスポットを特定する方法|perf record・perf reportでボトルネックを調査する実践手順
「CPU使用率が80%を超えているのに、どのプロセスのどの処理が重いのか特定できない」

top コマンドはプロセス単位で CPU 使用率を見せてくれるが、「そのプロセスの内部でどの関数が CPU 時間を消費しているか」までは教えてくれない。mpstat や sar で詳細な統計を取っても、負荷の「出どころ」を関数レベルで掴む手段にはならない。

そこで使うのが perf(Linux Performance Events)だ。Linux カーネルに組み込まれたパフォーマンス計測フレームワークで、CPU のハードウェアカウンター(PMU)を使ったサンプリングにより「どの関数が何%の CPU 時間を占めているか」を可視化できる。この記事では perf statperf recordperf reportperf top の実践的な使い方を、実機出力とトラブルシューティングを交えながら解説する。

動作確認環境: RHEL 9.4 / Ubuntu 24.04 LTS(kernel 6.8 系)

この記事のポイント

・perf record でサンプリングし perf report で関数レベルのホットスポットを特定できる
・perf stat でキャッシュミス・分岐予測ミスなど CPU イベントを数値で計測できる
・Permission denied は /proc/sys/kernel/perf_event_paranoid を 1 に緩めると解消する
・カーネルシンボルが [unknown] になる場合は debuginfo パッケージの導入が必要


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜ perf が必要か(top では見えない問題)

top・vmstat・mpstat・sar といったツールは「CPU 全体やプロセス全体の使用率を把握する」ために優れているが、次の問いには答えられない。

Web サーバーのどのリクエスト処理パスが重いか
カーネル内のどのシステムコールに CPU 時間が消えているか
L3 キャッシュミスや分岐予測ミスが性能劣化の原因か

perf は CPU の PMU(Performance Monitoring Unit)ハードウェアカウンターに直接アクセスし、一定頻度でスタックトレースをサンプリングすることでこれらの問いに答える。サンプリング方式なのでオーバーヘッドは低く、本番サーバーで短時間実行しても影響は許容範囲に収まる(-F 99 でサンプリング頻度を 1 秒 99 回に絞るのが本番の定番)。

perf のインストールと動作確認

perf は Linux カーネルのソースツリーに同梱されているが、実行バイナリはディストリビューション別のパッケージとして提供される。

1. インストール

RHEL 9 / AlmaLinux / Rocky Linux の場合:

# perf 本体 dnf install -y perf # カーネルデバッグシンボル(シンボル名を表示するため推奨) dnf debuginfo-install -y kernel-$(uname -r)

Ubuntu 24.04 LTS の場合:

# 実行中カーネルに対応する perf バイナリ apt install -y linux-tools-$(uname -r) linux-tools-generic

注意: Ubuntu では linux-tools-generic だけを入れると、実行カーネルとバージョンが食い違い「WARNING: perf not found for kernel X.X.X」と表示されることがある。uname -r で確認したカーネルバージョンと一致するパッケージを必ず導入すること。

2. バージョン確認

perf --version

実機出力例:

perf version 6.8.12

perf stat で CPU イベントの統計を取得する

perf stat は、コマンドの実行中に CPU サイクル数・命令数・キャッシュミス数・分岐予測ミス数などのハードウェアイベントを計測する。「処理が遅い原因が CPU 演算なのかメモリアクセスなのか」を数値で判断する第一歩になる。

1. コマンドに直接渡して計測する

perf stat find /var -name "*.log" 2>/dev/null

実機出力例(/var 配下のログファイル検索):

Performance counter stats for 'find /var -name *.log': 214.83 msec task-clock # 0.924 CPUs utilized 187 context-switches # 870.460 /sec 3 cpu-migrations # 13.960 /sec 2,418 page-faults # 11.255 K/sec 586,412,302 cycles # 2.729 GHz 964,173,881 instructions # 1.64 insn per cycle 197,482,034 branches # 919.185 M/sec 2,741,304 branch-misses # 1.39% of all branches 73,941,208 cache-references # 344.183 M/sec 4,182,903 cache-misses # 5.66% of all cache refs 0.232474 seconds time elapsed

出力の読み方:
insn per cycle(IPC): 1 クロックあたりの命令数。CPU が効率的に動いているかの指標。1.0 以下なら待ち時間(メモリアクセス待ちや分岐ミス待ち)が多い
cache-misses / cache-references: キャッシュミス率。5% を超えてくると、メモリアクセスがボトルネックになっている可能性が高い
branch-misses: 分岐予測ミス率。5% を超えると、条件分岐の多いコードパスが性能を引き下げている可能性がある

2. 実行中プロセスにアタッチして計測する

すでに起動済みのプロセスに対しては -p オプションで PID を指定する。sleep を組み合わせると計測時間を秒単位で指定できる。

# httpd の PID を取得して 10 秒計測する perf stat -p $(pgrep -n httpd) sleep 10

Web サーバーや DB サーバーなど常駐プロセスの負荷調査でよく使う場面だ。

3. システム全体を計測する

-a オプションで全 CPU コア・全プロセスをまとめて計測できる。

# 30 秒間、システム全体の CPU イベントを計測する perf stat -a sleep 30

どのプロセスが重いか当たりがついていない時の「最初の一手」として有効だ。

perf record と perf report でホットスポットを特定する

perf stat でイベント数を把握したら、次は「どの関数が CPU を消費しているか」を特定する。perf record でサンプリングデータを収集し、perf report で可視化するのが perf の核心的な使い方だ。

1. perf record でサンプリングデータを収集する

特定のコマンドをプロファイリングする場合:

perf record -g -F 99 ./myapp

実行中のプロセスに 30 秒アタッチする場合:

perf record -g -F 99 -p $(pgrep -n httpd) sleep 30

主要オプションの意味:
-g(--call-graph): コールグラフ(スタックトレース)を記録する。これがないと「どこから呼ばれているか」が見えない
-F 99: サンプリング頻度を 1 秒あたり 99 回に設定する。デフォルトの 1000Hz は本番では避け、99Hz に絞るのが安全な運用の定番
-p PID: 特定プロセスにアタッチする

実行が終わる(または Ctrl+C で中断する)と、カレントディレクトリに perf.data が生成される。

[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.487 MB perf.data (1243 samples) ]

2. perf report で関数別 CPU 使用率を確認する

perf report --stdio

--stdio を付けるとテキスト出力になり、lessgrep で読み込みやすくなる。付けない場合は対話的な TUI 画面が開く。

実機出力例(httpd 負荷テスト中のサンプリング結果):

# Samples: 1K of event 'cycles:P' # Event count (approx.): 2716438820 # # Overhead Command Shared Object Symbol # ........ ....... .................. ............................... # 47.83% httpd httpd [.] ap_run_handler 12.41% httpd libapr-1.so.0 [.] apr_pollset_poll 9.17% httpd [kernel] [k] __softirqentry_text_start 6.08% httpd httpd [.] ap_process_request 5.21% httpd libc.so.6 [.] __strcmp_avx2 4.34% httpd httpd [.] ssl_callback_ServerHello 2.93% httpd [kernel] [k] sock_recvmsg 1.89% httpd [kernel] [k] tcp_recvmsg 1.24% httpd httpd [.] ap_read_request

出力の読み方:
Overhead: この関数(シンボル)が全サンプルに占める割合。上位に来るほど CPU を多く使っているボトルネック候補
Shared Object の [kernel]: カーネル空間での処理。I/O やネットワークのシステムコストがここに出る
Symbol が [unknown]: デバッグシンボルが不足している。後述のトラブルシュートを参照

コールグラフ(呼び出し元チェーン)を展開して確認するには --call-graph=dwarf を追加する:

perf report --stdio --call-graph=dwarf | head -100

重い関数の「上流にあるコードパス」が木構造で表示される。修正すべき箇所を絞り込む際に効果的だ。

perf top でリアルタイムにホットスポットを確認する

perf top は top コマンドの関数版で、「今この瞬間どの関数が CPU を使っているか」をリアルタイムで表示する。perf.data への保存が不要なため、perf record より手軽に使える。

perf top -F 99 -g

TUI 画面を開かずテキスト出力にしたい場合:

perf top -F 99 --stdio

対話モード(TUI)での主なショートカット:
Enter キー: 選択した関数のコールグラフを展開する
A キー: アノテーション表示(アセンブリコードとシンボルの対応)
E キー: ソースコード表示(debuginfo がある場合のみ)
q キー: 終了

本番サーバーで「今すぐ重い関数を確認したい」場面では perf top が最速の手段だ。

「Permission denied」エラーとシンボル未表示のトラブルシュート

「You may not have permission to collect system-wide stats」が出る場合

root 以外のユーザーが perf を実行すると権限エラーになることがある。原因は /proc/sys/kernel/perf_event_paranoid の設定値だ。

cat /proc/sys/kernel/perf_event_paranoid

実機出力例(RHEL 9 のデフォルト):

3

値の意味:
-1: すべての計測を一般ユーザーに許可(セキュリティリスクあり)
0: 一般ユーザーが CPU ハードウェアカウンターを使える
1: カーネル空間プロファイリングを除き一般ユーザーも使える(本番で緩める場合の推奨値)
2(Ubuntu のデフォルト): root と CAP_PERFMON 権限を持つユーザーのみ
3(RHEL 9 のデフォルト): root と CAP_PERFMON のみ。システム全体の計測は禁止

一時的に緩める(再起動で元に戻る):

echo 1 | sudo tee /proc/sys/kernel/perf_event_paranoid

永続化する場合は /etc/sysctl.d/99-perf.conf を作成して sysctl --system を実行する:

kernel.perf_event_paranoid = 1

カーネルシンボルが [unknown] になる場合

perf report の Symbol 列が大部分 [unknown] になる場合、カーネルデバッグシンボルが入っていない。

RHEL 9 / AlmaLinux / Rocky Linux:

dnf debuginfo-install kernel-$(uname -r)

Ubuntu 24.04:

# Ubuntu Debugsymbols リポジトリを有効化 echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse" \ | sudo tee /etc/apt/sources.list.d/ddebs.list sudo apt install ubuntu-dbgsym-keyring sudo apt update sudo apt install linux-image-$(uname -r)-dbgsym

アプリケーション自体のシンボルが見えない場合は、コンパイル時に -g(デバッグ情報)と -fno-omit-frame-pointer(フレームポインタ保持)を付けてリビルドする。これがないと関数名やコールグラフが正確に取れない。

「WARNING: Kernel address maps are restricted」が出る場合

/proc/sys/kernel/kptr_restrict の値が高いと、カーネルシンボルへのアクセスが制限される。

# 現在の値を確認する cat /proc/sys/kernel/kptr_restrict # 一時的に解除する(再起動で元に戻る) echo 0 | sudo tee /proc/sys/kernel/kptr_restrict

計測完了後は必ず元の値(RHEL 9 では 1、Ubuntu では 2 が多い)に戻すこと。

perf でボトルネックを特定できたら、次はサーバー全体のパフォーマンスチューニングスキルを体系的に固めませんか?

perf のような「見えない障害を可視化する技術」を現場で使いこなせるのは、Linuxの内部構造を体系的に理解しているエンジニアだけです。
ネットの断片情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

本記事のまとめ

やりたいこと コマンド
コマンドの CPU イベントを計測する perf stat ./myapp
実行中プロセスを 10 秒計測する perf stat -p PID sleep 10
システム全体を 30 秒計測する perf stat -a sleep 30
コマンドをサンプリングして perf.data を生成 perf record -g -F 99 ./myapp
実行中プロセスを 30 秒サンプリング perf record -g -F 99 -p PID sleep 30
関数別 CPU 使用率をテキストで確認 perf report --stdio
コールグラフ付きで確認する perf report --stdio --call-graph=dwarf
リアルタイムにホットスポットを確認 perf top -F 99 -g
権限エラーを一時的に解除する echo 1 | sudo tee /proc/sys/kernel/perf_event_paranoid
カーネルシンボルアクセス制限を一時解除 echo 0 | sudo tee /proc/sys/kernel/kptr_restrict

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。