サーバー運用者必見|vmstatの見方・使い方を徹底解説【Linux パフォーマンス監視】
- 作成日 2026.06.24
- その他
サーバーが重い、レスポンスが遅い——そんな場面で最初に実行すべきコマンドのひとつが vmstat です。
vmstat(Virtual Memory Statistics)はCPU・メモリ・スワップ・ディスクI/O・コンテキストスイッチを1つのコマンドで一覧表示できる、サーバー運用者にとって欠かせないツールです。しかし、
- 出力の各列が何を意味するのか分からない
- 数値が正常なのか異常なのか判断できない
- 負荷の原因がCPUなのかメモリなのかIOなのか切り分けられない
topやiostatとの使い分けが分からない
という声をよく聞きます。
本記事では vmstat の出力を完全に読み解けるようになることを目標に、各フィールドの意味・正常値・危険なサインの見分け方・実際の負荷調査手順まで徹底解説します。
結論:先に答えを出す
# 基本:2秒ごとに継続表示(負荷調査の基本形)
vmstat 2
# 10回だけ表示
vmstat 2 10
# タイムスタンプ付きで表示(ログ記録に便利)
vmstat -t 2
# ディスクI/Oの詳細を表示
vmstat -d 2
# メモリをMB単位で表示
vmstat -S M 2
危険なサインのチェックポイント:
procs の r(実行待ちプロセス数) > CPUコア数 → CPU 不足
memory の swpd(スワップ使用量)> 0 かつ増加中 → メモリ不足
swap の si/so(スワップイン/アウト)> 0 → メモリ枯渇
io の bi/bo(ブロックI/O)が継続的に高い → ディスクI/O 高負荷
cpu の wa(I/O 待機)> 20% → I/O ボトルネック
cpu の st(スチール)> 5% → 仮想化環境での CPU 競合
vmstat の基本構文
vmstat [オプション] [インターバル [回数]]
インストール確認
# vmstat は procps パッケージに含まれる
vmstat --version
# インストールされていない場合
sudo apt install procps # Ubuntu/Debian
sudo dnf install procps # RHEL/CentOS/Fedora
オプション一覧
| オプション | 説明 |
|---|---|
-a | メモリをアクティブ/非アクティブで表示 |
-d | ディスクI/Oの統計を表示 |
-D | ディスク統計のサマリを表示 |
-f | 起動からのフォーク数を表示 |
-m | スラブ(カーネルメモリ)情報を表示 |
-n | ヘッダーを1回だけ表示 |
-s | メモリ統計のサマリをイベントカウンタで表示 |
-S M | 単位をメガバイトに変更(K・M・k・m) |
-t | タイムスタンプを追加 |
-w | 幅を広げて表示(数値が大きい場合に有効) |
出力の見方:フィールド完全解説
まず vmstat 2 の典型的な出力を見てみます。
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 512048 24832 1843200 0 0 5 12 450 890 15 3 81 1 0
0 0 0 511200 24832 1843208 0 0 0 16 420 820 10 2 87 1 0
2 0 0 510400 24840 1843220 0 0 0 8 480 950 20 4 75 1 0
procs(プロセス)
procs
r b
1 0
| フィールド | 意味 | 正常値 | 危険なサイン |
|---|---|---|---|
r | 実行中または実行待ち(Run queue)のプロセス数 | CPUコア数以下 | CPUコア数を継続的に超える |
b | I/O待ち・スリープ中のプロセス数(Blocked) | 0〜数個 | 継続的に増加する |
r(Run queue)の読み方:
CPUコア数 = 4 の場合
r = 1〜4 → 正常(CPUに余裕あり)
r = 5〜8 → やや混雑(レスポンスが遅くなり始める)
r > 8 → CPU ボトルネック(深刻な負荷)
# CPUコア数を確認
nproc
grep -c processor /proc/cpuinfo
b(Blocked)の読み方:
b が継続的に大きい場合はI/Oのボトルネックを疑います。ディスクの応答が遅く、多くのプロセスがI/O完了を待っている状態です。
memory(メモリ)
-----------memory----------
swpd free buff cache
0 512048 24832 1843200
| フィールド | 意味 | 単位 |
|---|---|---|
swpd | 使用中のスワップ領域 | KB |
free | 未使用の物理メモリ | KB |
buff | バッファキャッシュ(ブロックデバイスのメタデータ) | KB |
cache | ページキャッシュ(ファイルデータのキャッシュ) | KB |
Linuxのメモリの考え方:
実際に利用可能なメモリ = free + buff + cache
Linuxは空きメモリをできるだけキャッシュとして使います。free が少なくても cache が大きければ問題ありません。OSは必要になったらキャッシュを解放します。
# 実際の空きメモリを確認
free -h
# MemAvailable の値が実質的な空きメモリ
# vmstat と free の対応
vmstat -S M 1 1 # MB 単位で表示
free -m
危険なサイン:
swpd が 0 より大きく、増加し続けている
→ メモリが不足してスワップを使い始めている
free + cache が極端に少ない
→ メモリが枯渇に近い状態
-a オプションでの表示:
vmstat -a 2
procs -----------memory----------
r b swpd free inact active
| フィールド | 意味 |
|---|---|
inact | 非アクティブメモリ(しばらくアクセスされていない) |
active | アクティブメモリ(最近アクセスされた) |
swap(スワップ)
---swap--
si so
0 0
| フィールド | 意味 | 正常値 | 危険なサイン |
|---|---|---|---|
si | スワップイン(ディスク→メモリへの読み込み) KB/s | 0 | 継続的に > 0 |
so | スワップアウト(メモリ→ディスクへの書き出し) KB/s | 0 | 継続的に > 0 |
スワップの読み方:
si・so がともに 0 であれば正常です。これらが継続的に発生している場合、メモリが物理的に不足しており、パフォーマンスに深刻な影響が出ています。
si/so が断続的に発生 → メモリ不足の兆候
si/so が継続的に高い → スラッシング(深刻な状態)
スラッシングとは、スワップイン/アウトが頻繁に繰り返され、CPUがほぼディスクI/O待ちになってしまう状態です。この状態ではサーバーはほとんど仕事ができません。
io(ブロックI/O)
-----io----
bi bo
5 12
| フィールド | 意味 | 単位 |
|---|---|---|
bi | ブロックデバイスからの読み込み(Block In) | blocks/s |
bo | ブロックデバイスへの書き込み(Block Out) | blocks/s |
1ブロックは通常512バイトです。
io の読み方:
bi/bo が低い(〜数百) → 正常
bi/bo が高い(数千〜) → ディスクI/O 高負荷
bi が高い → 読み込み多い(DBのフルスキャン・ログ読み込み等)
bo が高い → 書き込み多い(ログ書き込み・DBのフラッシュ等)
bi が高い場合はページキャッシュが機能していない可能性があります(memory の cache を確認)。
system(システム)
-system--
in cs
450 890
| フィールド | 意味 | 正常値 |
|---|---|---|
in | 割り込み回数/秒(Interrupts) | 負荷に応じて変動 |
cs | コンテキストスイッチ回数/秒(Context Switches) | 負荷に応じて変動 |
コンテキストスイッチ(cs)の読み方:
コンテキストスイッチはCPUが別のプロセスに切り替わる処理で、それ自体にオーバーヘッドがあります。
cs が 数百〜数千 → 通常の範囲
cs が 数万〜数十万 → 過剰なコンテキストスイッチ(要調査)
コンテキストスイッチが多い原因:
- スレッド数が多すぎる
- ロック競合が多い(スレッドが頻繁に待機・再開する)
procsのrと合わせて確認する
# プロセスごとのコンテキストスイッチを確認
cat /proc/<PID>/status | grep ctxt
# voluntary_ctxt_switches:自発的(I/O待ちなど)
# nonvoluntary_ctxt_switches:非自発的(タイムスライス切れ)
cpu(CPU使用率)
------cpu-----
us sy id wa st
15 3 81 1 0
| フィールド | 意味 | 正常値 | 危険なサイン |
|---|---|---|---|
us | ユーザー空間のCPU使用率(User) | 用途による | 長時間90%超 |
sy | カーネル空間のCPU使用率(System) | 10%以下 | 継続的に20%超 |
id | アイドル率(Idle) | 高いほど良い | 継続的に10%未満 |
wa | I/O待ち時間(Wait) | 5%以下 | 継続的に20%超 |
st | 仮想マシンから盗まれたCPU時間(Steal) | 0〜1% | 継続的に5%超 |
us + sy + id + wa + st = 100% になります。
各フィールドの詳細:
us(User):
アプリケーション(Webサーバー・DB・スクリプト等)によるCPU使用率です。高い場合はアプリの処理が多い状態で、必ずしも問題ではありません。ただし長時間90%を超える場合はスケールアップ・水平スケールを検討します。
sy(System):
カーネルの処理(システムコール・割り込み処理等)によるCPU使用率です。通常は10%以下が目安。高い場合はシステムコールが多すぎる、ネットワークI/Oが激しい、コンテキストスイッチが多いなどの原因が考えられます。
wa(Wait):
CPUがI/O完了を待っている時間の割合です。継続的に高い場合はディスクI/Oがボトルネックです。
wa > 5% → ディスクI/Oに注意
wa > 20% → I/Oボトルネックの可能性が高い
wa > 40% → 深刻なI/O問題
st(Steal):
仮想マシン(クラウドのEC2・GCEなど)でのみ発生します。ハイパーバイザーが他の仮想マシンのためにCPUを「盗んでいる」時間の割合です。
st > 5% → 他の仮想マシンとCPUを激しく競合している
→ インスタンスタイプのアップグレードを検討
実践:負荷の原因を切り分ける
診断フローチャート
vmstat 2 を実行
│
├─ r > CPUコア数が続く?
│ ├─ Yes → CPU ボトルネック
│ │ us が高い → アプリの処理量が多い
│ │ sy が高い → システムコール・割り込みが多い
│ │ st が高い → 仮想マシンのCPU競合
│ └─ No ↓
│
├─ si/so > 0 が続く?
│ ├─ Yes → メモリ不足・スラッシング
│ │ free + cache を確認
│ │ メモリリークの可能性
│ └─ No ↓
│
├─ wa > 20% が続く?
│ ├─ Yes → I/O ボトルネック
│ │ bi が高い → 読み込み多い
│ │ bo が高い → 書き込み多い
│ │ iostat でデバイス別に詳細確認
│ └─ No ↓
│
├─ b > 0 が続く?
│ ├─ Yes → I/O待ちプロセスあり
│ │ iostat・iotop で詳細確認
│ └─ No ↓
│
└─ cs が異常に高い?
├─ Yes → コンテキストスイッチ過多
│ スレッド数・ロック競合を確認
└─ No → 負荷は正常範囲
シナリオ1:CPU 負荷が高い
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
8 0 0 1024000 12000 800000 0 0 0 4 200 400 92 5 2 1 0
7 0 0 1024000 12000 800000 0 0 0 2 210 410 90 6 3 1 0
読み方:
r = 8:CPUコア数(例:4コア)を超えて実行待ちプロセスが多いus = 92%:アプリが CPU をほぼ独占id = 2%:アイドルがほぼない
対処:
# CPU を使っているプロセスを特定
top -b -n 1 | head -20
ps aux --sort=-%cpu | head -10
# プロセスの詳細を確認
pidstat -u 1 5
# アプリのプロファイリング(Python の例)
py-spy top --pid <PID>
シナリオ2:メモリ不足・スワップが発生
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 3 51200 4096 512 20480 128 256 2048 512 300 600 20 8 10 62 0
3 4 65536 2048 512 18432 256 512 4096 1024 400 800 15 10 5 70 0
読み方:
swpd = 65536(64MB):スワップを使用中かつ増加しているsi = 256, so = 512:スワップイン/アウトが継続発生b = 4:I/O待ちプロセスが多いwa = 70%:CPUのほとんどがI/O待ちfree = 2048(2MB):物理メモリが枯渇
対処:
# メモリを使っているプロセスを特定
ps aux --sort=-%mem | head -10
top -b -n 1 -o %MEM | head -20
# メモリリークの確認(時系列で増加しているか)
watch -n 5 'ps aux --sort=-%mem | head -10'
# スワップの詳細確認
cat /proc/swaps
swapon --show
# OOM Killer のログを確認
dmesg | grep -i "out of memory"
dmesg | grep -i "oom"
grep -i "oom" /var/log/syslog
シナリオ3:ディスクI/O 高負荷
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 5 0 800000 32000 1200000 0 0 8192 4096 600 900 5 3 62 30 0
0 6 0 800000 32000 1200000 0 0 12288 8192 700 950 3 2 55 40 0
読み方:
b = 6:I/O待ちプロセスが多いbi = 12288, bo = 8192:大量のディスクI/Owa = 40%:CPUの40%がI/O待ちus = 3%:アプリの処理自体は少ない
対処:
# I/O を使っているプロセスを特定
iotop -o # I/O を使っているプロセスだけ表示
iotop -a # 累積I/O量を表示
# デバイス別のI/O統計
iostat -xz 2
# どのファイルにアクセスしているか
lsof +D /var/log # 特定ディレクトリへのアクセス
lsof -p <PID> # 特定プロセスが開いているファイル
シナリオ4:仮想マシンでのCPU競合
------cpu-----
us sy id wa st
20 5 30 5 40
読み方:
st = 40%:CPUの40%が仮想マシンの外に盗まれているid = 30%:アイドルはあるが st のせいで性能が出ていない
対処:
- クラウドプロバイダーのコンソールで CPU クレジット残量を確認(AWS の t系インスタンスなど)
- 上位のインスタンスタイプへのアップグレードを検討
- 専有インスタンス・専有ホストへの移行を検討
継続監視・ログ取得
ファイルに出力して保存
# タイムスタンプ付きでファイルに保存
vmstat -t 2 >> /var/log/vmstat.log
# バックグラウンドで実行
nohup vmstat -t 2 >> /var/log/vmstat.log &
# 1時間分(30分×60秒/2秒=900回)を記録
vmstat -t 2 900 > /var/log/vmstat_$(date +%Y%m%d_%H%M).log
cron で定期記録
# /etc/cron.d/vmstat-monitor
# 5分ごとに記録
*/5 * * * * root vmstat -t 1 5 >> /var/log/vmstat.log 2>&1
# ログローテーション設定
# /etc/logrotate.d/vmstat
/var/log/vmstat.log {
daily
rotate 7
compress
missingok
notifempty
}
急な負荷上昇を記録するスクリプト
#!/bin/bash
# /usr/local/bin/vmstat-alert.sh
# CPU 使用率が閾値を超えたら詳細を記録
THRESHOLD_R=8 # run queue の閾値
LOG=/var/log/vmstat-alert.log
while true; do
R=$(vmstat 1 2 | tail -1 | awk '{print $1}')
WA=$(vmstat 1 2 | tail -1 | awk '{print $16}')
if [ "$R" -gt "$THRESHOLD_R" ] || [ "$WA" -gt 30 ]; then
echo "=== $(date) ===" >> "$LOG"
echo "r=$R wa=$WA" >> "$LOG"
vmstat -t 1 10 >> "$LOG"
top -b -n 1 | head -20 >> "$LOG"
iostat -x 1 3 >> "$LOG"
echo "" >> "$LOG"
fi
sleep 10
done
vmstat のその他の使い方
-d でディスクI/O統計
vmstat -d 2
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
sda 12345 234 456789 12345 67890 123 345678 9876 0 45
| フィールド | 意味 |
|---|---|
reads total | 総読み込み回数 |
reads sectors | 読み込みセクター数 |
reads ms | 読み込みにかかった合計時間(ms) |
writes total | 総書き込み回数 |
cur | 現在処理中のI/O数 |
sec | I/O処理にかかった合計秒数 |
-s でメモリイベントサマリ
vmstat -s
8192000 K total memory
1024000 K used memory
2048000 K active memory
1536000 K inactive memory
5120000 K free memory
24832 K buffer memory
1843200 K swap cache
2097148 K total swap
0 K used swap
2097148 K free swap
1234 non-nice user cpu ticks
123 nice user cpu ticks
456 system cpu ticks
78901 idle cpu ticks
234 IO-wait cpu ticks
45 IRQ cpu ticks
89 softirq cpu ticks
0 stolen cpu ticks
123456 pages paged in
67890 pages paged out
0 pages swapped in
0 pages swapped out
45678 interrupts
89012 CPU context switches
1234567890 boot time
12345 forks
-m でスラブキャッシュ
vmstat -m
カーネルのメモリアロケータ(slab)の使用状況を表示します。カーネルのメモリリーク調査に使います。
他のコマンドとの使い分け
| コマンド | 得意な情報 | 使うタイミング |
|---|---|---|
vmstat | CPU・メモリ・スワップ・I/O の概観 | 最初に実行する・全体像の把握 |
top / htop | プロセスごとのCPU・メモリ使用率 | 原因プロセスを特定する |
iostat | デバイスごとのI/O詳細 | I/Oボトルネックの詳細調査 |
iotop | プロセスごとのI/O使用量 | I/Oを使っているプロセスを特定 |
sar | 過去の履歴・グラフ | 時系列での傾向分析 |
free | メモリの詳細 | メモリ使用量の詳細確認 |
mpstat | CPUコアごとの使用率 | マルチコアのバランスを確認 |
pidstat | プロセスごとのCPU・I/O | 特定プロセスの詳細 |
dstat | vmstatの上位互換 | より見やすい統合表示 |
負荷調査の典型的な流れ
# Step 1:全体像を把握(vmstat)
vmstat 2
# Step 2:CPU 高負荷なら原因プロセスを特定
top -b -n 1 | head -20
ps aux --sort=-%cpu | head -10
# Step 3:I/O 高負荷なら詳細を確認
iostat -xz 2
iotop -o
# Step 4:メモリ不足なら使用量を確認
free -h
ps aux --sort=-%mem | head -10
# Step 5:過去の傾向を確認
sar -u 1 10 # CPU の履歴
sar -r 1 10 # メモリの履歴
sar -b 1 10 # I/O の履歴
トラブルシューティング
数値の単位が分かりにくい
# MB 単位で表示
vmstat -S M 2
# 幅を広げて表示(桁あふれ防止)
vmstat -w 2
最初の1行は無視する
# vmstat の最初の行は起動からの累積値(瞬間値ではない)
vmstat 2
# 1行目:起動からの累積
# 2行目以降:インターバルごとの差分(こちらを見る)
# 最初の1行を除外して表示
vmstat 2 | tail -n +4
タイムスタンプを付けて管理しやすくする
# タイムスタンプ付き
vmstat -t 2
# または date と組み合わせ
while true; do
echo -n "$(date '+%Y-%m-%d %H:%M:%S') "
vmstat 1 2 | tail -1
sleep 2
done
よくある質問(FAQ)
Q1. free が少ないのにメモリ不足ではない理由は?
Linuxは空きメモリをできるだけファイルキャッシュ(cache)として活用します。free が少なくても cache が大きければ正常です。本当の空きメモリは free + buff + cache と考えてください。メモリが必要になれば OS がキャッシュを解放します。
# 実際に利用可能なメモリを確認
free -h
# Mem 行の「available」が実質的な空きメモリ
Q2. vmstat 2 の最初の行だけ数値が大きいのはなぜ?
最初の行は OS 起動からの累積値です。2行目以降が指定したインターバル(この場合2秒)ごとの差分値になります。通常は2行目以降を見てください。
Q3. wa が高いのに bi・bo が低い場合は?
NFS・CIFS などのネットワークファイルシステムのI/O待ちの場合、bi・bo には現れないことがあります。iostat で確認するか、nfsstat でNFSの統計を確認してください。
nfsstat -c # NFS クライアント統計
iostat -x 2 # デバイス別詳細
Q4. cs(コンテキストスイッチ)はいくつが正常ですか?
用途によって大きく異なります。サーバーの種類・スレッド数・負荷によって1秒間に数百〜数万は許容範囲です。問題になるのは急激に増加したり、sy(システムCPU)も連動して上昇している場合です。
# コンテキストスイッチが多いプロセスを確認
pidstat -w 1 5
Q5. 仮想マシンで st が高い場合の確認方法は?
# AWS の場合:CloudWatch で CPU クレジットを確認
# または以下で確認
cat /proc/stat | grep steal
# 時系列で確認
sar -u 1 10 | grep -E "^[0-9]"
# %steal の列を確認
Q6. vmstat と dstat の違いは?
dstat は vmstat・iostat・netstat・ifstat を統合した高機能版で、カラー表示・デバイス別表示など視認性が高いです。ただし追加インストールが必要です。
sudo apt install dstat
dstat -cdngy 2 # CPU・ディスク・ネット・ページ・システムを表示
まとめ
vmstat で最初に確認すべき項目を優先順で整理します。
vmstat 2 # まずこれを実行
見るべきポイント(優先順):
① procs の r > CPUコア数 → CPU ボトルネック
us 高い → アプリの処理量
sy 高い → システムコール多い
st 高い → 仮想マシンのCPU競合
② swap の si/so > 0 → メモリ不足
memory の free + cache を確認
OOM Killer のログを確認
③ cpu の wa > 20% → I/O ボトルネック
io の bi/bo を確認
iostat・iotop で詳細調査
④ system の cs が急増 → コンテキストスイッチ過多
スレッド数・ロック競合を確認
vmstat で全体像をつかみ、原因が見えてきたら top・iostat・iotop・sar で深掘りするというフローが、サーバー負荷調査の基本形です。
参考リンク
公式ドキュメント
関連コマンド
関連記事(本サイト)
- Linux grep オプション一覧 – grepコマンドリファレンス
- Linux「Too many open files」エラーの解決方法 – サーバー運用
- Linux「command not found」エラーの解決方法 – よくあるLinuxエラー
- apt vs apt-get 徹底比較 – パッケージ管理
本記事は2026年6月時点の情報をもとに、Ubuntu 24.04 LTS・procps 4.x での動作確認に基づき作成しています。カーネルバージョンやディストリビューションによって出力が異なる場合があるため、最新情報は各公式ドキュメントをご確認ください。
-
前の記事
【完全版】Rails Solid Queue の使い方|セットアップから本番運用・Sidekiqからの移行まで徹底解説 2026.06.24
-
次の記事
【完全版】CORSエラーの原因と解決方法まとめ|nginx・Express・Laravel別の設定と落とし穴を徹底解説 2026.06.24
コメントを書く