サーバー運用者必見|vmstatの見方・使い方を徹底解説【Linux パフォーマンス監視】

サーバー運用者必見|vmstatの見方・使い方を徹底解説【Linux パフォーマンス監視】

サーバーが重い、レスポンスが遅い——そんな場面で最初に実行すべきコマンドのひとつが vmstat です。

vmstat(Virtual Memory Statistics)はCPU・メモリ・スワップ・ディスクI/O・コンテキストスイッチを1つのコマンドで一覧表示できる、サーバー運用者にとって欠かせないツールです。しかし、

  • 出力の各列が何を意味するのか分からない
  • 数値が正常なのか異常なのか判断できない
  • 負荷の原因がCPUなのかメモリなのかIOなのか切り分けられない
  • topiostat との使い分けが分からない

という声をよく聞きます。

本記事では 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単位をメガバイトに変更(KMkm
-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コア数を継続的に超える
bI/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/s0継続的に > 0
soスワップアウト(メモリ→ディスクへの書き出し) KB/s0継続的に > 0

スワップの読み方:

siso がともに 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 が高い場合はページキャッシュが機能していない可能性があります(memorycache を確認)。


system(システム)

-system--
  in   cs
 450  890
フィールド意味正常値
in割り込み回数/秒(Interrupts)負荷に応じて変動
csコンテキストスイッチ回数/秒(Context Switches)負荷に応じて変動

コンテキストスイッチ(cs)の読み方:

コンテキストスイッチはCPUが別のプロセスに切り替わる処理で、それ自体にオーバーヘッドがあります。

cs が 数百〜数千    → 通常の範囲
cs が 数万〜数十万  → 過剰なコンテキストスイッチ(要調査)

コンテキストスイッチが多い原因:

  • スレッド数が多すぎる
  • ロック競合が多い(スレッドが頻繁に待機・再開する)
  • procsr と合わせて確認する
# プロセスごとのコンテキストスイッチを確認
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%未満
waI/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/O
  • wa = 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数
secI/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)の使用状況を表示します。カーネルのメモリリーク調査に使います。


他のコマンドとの使い分け

コマンド得意な情報使うタイミング
vmstatCPU・メモリ・スワップ・I/O の概観最初に実行する・全体像の把握
top / htopプロセスごとのCPU・メモリ使用率原因プロセスを特定する
iostatデバイスごとのI/O詳細I/Oボトルネックの詳細調査
iotopプロセスごとのI/O使用量I/Oを使っているプロセスを特定
sar過去の履歴・グラフ時系列での傾向分析
freeメモリの詳細メモリ使用量の詳細確認
mpstatCPUコアごとの使用率マルチコアのバランスを確認
pidstatプロセスごとのCPU・I/O特定プロセスの詳細
dstatvmstatの上位互換より見やすい統合表示

負荷調査の典型的な流れ

# 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 が高いのに bibo が低い場合は?

NFS・CIFS などのネットワークファイルシステムのI/O待ちの場合、bibo には現れないことがあります。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. vmstatdstat の違いは?

dstatvmstatiostatnetstatifstat を統合した高機能版で、カラー表示・デバイス別表示など視認性が高いです。ただし追加インストールが必要です。

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 で全体像をつかみ、原因が見えてきたら topiostatiotopsar で深掘りするというフローが、サーバー負荷調査の基本形です。


参考リンク

公式ドキュメント

関連コマンド

関連記事(本サイト)


本記事は2026年6月時点の情報をもとに、Ubuntu 24.04 LTS・procps 4.x での動作確認に基づき作成しています。カーネルバージョンやディストリビューションによって出力が異なる場合があるため、最新情報は各公式ドキュメントをご確認ください。