vmstat
vmstat
(Virtual Memory Statistics)是Linux系统性能监控工具,用于显示虚拟内存、进程、CPU活动等系统统计信息。
基本语法
vmstat [选项] [延迟] [次数]
主要选项
基本选项
-a, --active
- 显示活跃和非活跃内存-f, --forks
- 显示自系统启动以来的进程创建数-s, --stats
- 显示内存统计信息和系统活动-d, --disk
- 显示磁盘统计信息-D, --disk-sum
- 显示磁盘活动统计摘要-p, --partition
- 显示指定分区的统计信息
显示选项
-S, --unit
- 指定输出单位(k, K, m, M)-t, --timestamp
- 显示时间戳-n, --one-header
- 只显示一次头部信息-w, --wide
- 宽格式输出
时间选项
delay
- 更新间隔(秒)count
- 显示次数
输出字段解释
默认输出字段
# vmstat 输出示例
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 1234567 567 89012 0 0 5 10 123 456 2 1 97 0 0
Procs(进程)
r
- 运行队列中的进程数(等待CPU的进程)b
- 阻塞队列中的进程数(等待I/O的进程)
Memory(内存,单位KB)
swpd
- 已使用的虚拟内存大小free
- 空闲的物理内存大小buff
- 用作缓冲的内存大小cache
- 用作缓存的内存大小
Swap(交换空间)
si
- 每秒从磁盘读入虚拟内存的大小so
- 每秒从虚拟内存写入磁盘的大小
IO(输入/输出)
bi
- 每秒从块设备读取的块数bo
- 每秒向块设备写入的块数
System(系统)
in
- 每秒中断数,包括时钟中断cs
- 每秒上下文切换次数
CPU(处理器使用百分比)
us
- 用户进程消耗的CPU时间百分比sy
- 系统进程消耗的CPU时间百分比id
- CPU空闲时间百分比wa
- IO等待消耗的CPU时间百分比st
- 虚拟机偷取的CPU时间百分比
使用示例
基本监控
# 显示当前系统状态
vmstat
# 每2秒更新一次,共5次
vmstat 2 5
# 每5秒更新一次,持续监控
vmstat 5
# 显示时间戳
vmstat -t 1
内存监控
# 显示活跃和非活跃内存
vmstat -a
# 显示内存统计信息
vmstat -s
# 以MB为单位显示
vmstat -S M
# 监控内存使用趋势
vmstat -S M 5 12
磁盘监控
# 显示磁盘统计信息
vmstat -d
# 显示磁盘活动摘要
vmstat -D
# 监控特定分区
vmstat -p /dev/sda1
# 组合监控磁盘和内存
vmstat -d 3
进程监控
# 显示fork统计
vmstat -f
# 监控进程队列变化
vmstat 1 60
实际应用场景
系统性能分析
# 基础性能检查
echo "=== 系统性能概览 ==="
vmstat
echo -e "\n=== 内存详细信息 ==="
vmstat -s | head -20
echo -e "\n=== 磁盘活动统计 ==="
vmstat -D
CPU使用率监控
# 监控CPU使用情况
vmstat 1 10 | awk '
NR>2 {
total_cpu = 100 - $15 # id列是空闲百分比
print strftime("%H:%M:%S"), "CPU使用率:", total_cpu "%"
if (total_cpu > 80) print "警告: CPU使用率过高!"
}'
内存监控脚本
#!/bin/bash
# memory_monitor.sh
echo "内存使用监控"
echo "============"
vmstat -S M 1 5 | awk '
BEGIN {
print "时间\t\t内存使用率\t交换使用"
}
NR>2 {
# 计算内存使用率(假设总内存为从第一行获取)
used_mem = $4 + $5 + $6 # buff + cache + 其他
swap_used = $3
printf "%s\t%.1f%%\t\t%d MB\n", strftime("%H:%M:%S"),
(used_mem > 0 ? (used_mem/total_mem)*100 : 0), swap_used
}
'
I/O性能分析
#!/bin/bash
# io_monitor.sh
echo "I/O性能监控"
echo "=========="
vmstat 1 10 | awk '
NR==3 { next } # 跳过第一行统计数据
NR>3 {
print strftime("%H:%M:%S"),
"读取:", $9 "块/秒",
"写入:", $10 "块/秒",
"IO等待:", $16 "%"
if ($16 > 20) {
print "警告: IO等待时间过高(" $16 "%)"
}
}'
高级监控脚本
系统性能综合监控
#!/bin/bash
# system_performance.sh
INTERVAL=5
COUNT=12
LOG_FILE="/var/log/system_performance.log"
echo "系统性能监控 - $(date)" | tee -a $LOG_FILE
echo "====================================" | tee -a $LOG_FILE
# 获取系统基本信息
echo "系统信息:" | tee -a $LOG_FILE
uname -a | tee -a $LOG_FILE
echo | tee -a $LOG_FILE
# 监控开始
echo "开始监控 (间隔:${INTERVAL}秒, 次数:${COUNT})" | tee -a $LOG_FILE
echo | tee -a $LOG_FILE
vmstat $INTERVAL $COUNT | tee -a $LOG_FILE | awk '
BEGIN {
print "实时分析:"
cpu_high_count = 0
mem_swap_count = 0
io_wait_high = 0
}
NR>2 {
# CPU使用率分析
cpu_usage = 100 - $15
if (cpu_usage > 80) {
cpu_high_count++
print strftime("%H:%M:%S") " - 警告: CPU使用率过高 (" cpu_usage "%)"
}
# 内存交换分析
if ($8 > 0 || $9 > 0) {
mem_swap_count++
print strftime("%H:%M:%S") " - 警告: 检测到内存交换活动"
}
# I/O等待分析
if ($16 > 30) {
io_wait_high++
print strftime("%H:%M:%S") " - 警告: I/O等待时间过高 (" $16 "%)"
}
# 进程队列分析
if ($1 > 5) {
print strftime("%H:%M:%S") " - 注意: 运行队列较长 (" $1 "个进程)"
}
}
END {
print "\n监控总结:"
print "CPU使用率过高次数:", cpu_high_count
print "内存交换活动次数:", mem_swap_count
print "I/O等待过高次数:", io_wait_high
}'
性能基线建立脚本
#!/bin/bash
# performance_baseline.sh
DURATION=300 # 5分钟采样
INTERVAL=10 # 10秒间隔
SAMPLES=$((DURATION / INTERVAL))
echo "建立系统性能基线 (采样时间: ${DURATION}秒)"
echo "============================================"
vmstat $INTERVAL $SAMPLES | awk '
BEGIN {
cpu_sum = 0; mem_free_sum = 0; io_bi_sum = 0; io_bo_sum = 0
samples = 0
}
NR>2 {
samples++
cpu_sum += (100 - $15)
mem_free_sum += $4
io_bi_sum += $9
io_bo_sum += $10
# 记录峰值
if (NR == 3) {
cpu_max = cpu_min = 100 - $15
mem_min = mem_max = $4
io_max = $9 + $10
} else {
cpu_usage = 100 - $15
if (cpu_usage > cpu_max) cpu_max = cpu_usage
if (cpu_usage < cpu_min) cpu_min = cpu_usage
if ($4 > mem_max) mem_max = $4
if ($4 < mem_min) mem_min = $4
io_total = $9 + $10
if (io_total > io_max) io_max = io_total
}
}
END {
if (samples > 0) {
printf "性能基线报告 (%d个样本):\n", samples
printf "CPU使用率 - 平均: %.1f%%, 最高: %.1f%%, 最低: %.1f%%\n",
cpu_sum/samples, cpu_max, cpu_min
printf "空闲内存 - 平均: %.0f KB, 最高: %.0f KB, 最低: %.0f KB\n",
mem_free_sum/samples, mem_max, mem_min
printf "I/O活动 - 平均: %.1f 块/秒, 峰值: %.0f 块/秒\n",
(io_bi_sum + io_bo_sum)/samples, io_max
}
}'
故障排查应用
系统负载问题诊断
# 检查系统负载来源
echo "=== 系统负载分析 ==="
vmstat 1 5 | awk '
NR>2 {
run_queue = $1
blocked = $2
cpu_user = $13
cpu_system = $14
cpu_wait = $16
print "时间:", strftime("%H:%M:%S")
print "运行队列:", run_queue, "阻塞进程:", blocked
if (run_queue > 5) {
print "- 建议检查CPU密集型进程"
}
if (blocked > 2) {
print "- 建议检查I/O操作"
}
if (cpu_wait > 20) {
print "- 系统I/O等待过高,检查磁盘性能"
}
print "---"
}'
内存泄漏检测
#!/bin/bash
# memory_leak_detect.sh
echo "内存泄漏监控开始..."
PREV_FREE=0
vmstat 2 | while read line; do
if echo "$line" | grep -q "^ *[0-9]"; then
FREE=$(echo $line | awk '{print $4}')
CACHE=$(echo $line | awk '{print $6}')
if [ $PREV_FREE -ne 0 ]; then
DIFF=$((PREV_FREE - FREE))
if [ $DIFF -gt 10000 ]; then # 超过10MB差异
echo "$(date): 检测到内存快速消耗 - 减少 ${DIFF}KB"
echo "当前空闲内存: ${FREE}KB, 缓存: ${CACHE}KB"
fi
fi
PREV_FREE=$FREE
fi
done
性能调优建议
基于vmstat输出的调优
# CPU调优建议
if [ "$cpu_usage" -gt 80 ]; then
echo "CPU使用率过高建议:"
echo "1. 检查top命令找出CPU密集型进程"
echo "2. 考虑增加CPU核心或优化程序"
echo "3. 检查是否有死循环进程"
fi
# 内存调优建议
if [ "$swap_activity" -gt 0 ]; then
echo "内存交换活动建议:"
echo "1. 增加物理内存"
echo "2. 优化应用程序内存使用"
echo "3. 调整swappiness参数"
fi
# I/O调优建议
if [ "$io_wait" -gt 20 ]; then
echo "I/O等待过高建议:"
echo "1. 检查磁盘健康状态"
echo "2. 考虑使用SSD或更快的存储"
echo "3. 优化数据库查询和索引"
fi
注意事项
- 第一行数据: 第一行显示的是系统启动以来的平均值
- 采样频率: 频繁采样会增加系统开销
- 单位理解: 默认内存单位是KB,注意与其他工具的单位差异
- 上下文切换: 过高的cs值可能表示系统调度压力大
- 中断处理: 过高的in值可能表示硬件问题
相关命令
top
- 实时进程监控htop
- 增强版topiostat
- I/O统计信息sar
- 系统活动报告free
- 内存使用情况mpstat
- 多处理器统计
vmstat是Linux系统性能监控的基础工具,通过合理使用可以快速了解系统的整体性能状况。