4.7.3 内存使用分析工具:free、vmstat、top、pmap

内存使用分析是性能调优的基础,目标是区分真实内存压力、缓存占用与进程级泄漏。本节围绕 free、vmstat、top、pmap 四类工具,建立从系统级到进程级的排查路径、示例与指标解读方法。

原理草图(系统级到进程级):

文章图片

安装与准备(多数发行版默认包含,缺失时安装):

# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y procps

# RHEL/CentOS/Rocky
sudo yum install -y procps-ng

# 验证
free --version
vmstat -V
top -v
pmap -V

free:快速查看总体内存与缓存结构
- 常用命令与解释:

free -h      # 人类可读单位
free -m      # 以 MB 显示,便于脚本处理
free -h -s 2 # 每 2 秒刷新一次
  • 关键字段说明:
  • total/used/free:总体、已用、空闲
  • buff/cache:页缓存与内核缓存
  • available:可用内存(真实压力判断首选)
  • swap total/used/free:交换分区使用
  • 示例输出与判读:
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           31Gi       7.2Gi       1.1Gi       512Mi        22Gi        23Gi
Swap:         2.0Gi       128Mi       1.9Gi

# 判读:available 高、swap 低 -> 内存压力不大

vmstat:观察内存与调度的动态变化
- 常用命令与解释:

vmstat 1 10  # 每秒采样 10vmstat -S M 1 5  # 以 MB 显示,便于观察
  • 重点列:
  • swpd:已使用 swap
  • free/buff/cache:内存结构
  • si/so:swap in/out,持续非零说明频繁换页
  • r/b:运行/阻塞进程数,b 高可能是 I/O 或内存压力
  • 示例输出与判读:
$ vmstat 1 3
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 131072 118000 12000 620000   10   15   200   180  600 1200 12  5 70 13  0

# 判读:si/so 持续非零 + swpd 增长 -> 发生换页,可能内存抖动

top:定位内存大户与实时趋势
- 常用命令与解释:

top          # 进入后按 M 按内存排序,P 按 CPU 排序
top -p 1234  # 只看指定进程
  • 关注字段:
  • %MEM、RES(常驻内存)、VIRT(虚拟内存)
  • SHR(共享内存)
  • 示例说明:
# top 中 %MEM 持续上升且 RES 增长 -> 进程可能泄漏
# VIRT 很大但 RES 小 -> 可能是 mmap 或预留地址空间

pmap:进程级内存映射精细分析
- 常用命令与解释:

pmap -x 1234 | head -n 20   # 查看前 20 行
pmap -x 1234 | tail -n 5    # 查看汇总
  • 关键列:
  • total、rss、dirty
  • 各段映射(heap、stack、anon、file)
  • 示例输出与判读:
$ pmap -x 1234 | tail -n 5
total kB     1048576  512000  128000
# total: 虚拟内存总量
# rss: 常驻内存
# dirty: 脏页,持续增长可能为泄漏或写入频繁

排查路径(可执行流程):

# 1) 系统级压力判断
free -h

# 2) 动态换页/抖动判断
vmstat 1 5

# 3) 定位内存大户
top -o %MEM

# 4) 进程段定位
PID=1234
pmap -x "$PID" | grep -E "heap|anon|stack" | head

常见问题与排错示例
1) free 显示 used 很高,但 available 很大
- 原因:页缓存占用,不是真实压力
- 处理:无需释放缓存,除非业务确实内存不足

free -h
# 观察 available 是否低于基线

2) vmstat si/so 持续非零,系统卡顿
- 排查:确认 swap 是否增长,是否有内存大户

vmstat 1 10
top -o %MEM
# 若 swap 持续上升,考虑优化应用内存或扩容

3) 进程 RES 持续增长
- 排查:pmap 查看 heap/anon 是否增长

PID=1234
pmap -x $PID | grep -E "heap|anon"
# 若 heap/rss 持续增长,结合应用日志和版本变更排查泄漏

4) pmap 输出过大难分析
- 处理:按段统计

pmap -x 1234 | awk 'NR>2 {sum[$6]+=$2} END{for(k in sum) print k, sum[k]"K"}'
# 统计各段占用

练习
1) 编写脚本,每 5 秒采集一次 free/available 与 swap used,连续 1 分钟。
2) 使用 vmstat 1 10,判断是否存在换页抖动,并记录 si/so。
3) 使用 top 找出前 3 个内存占用进程,并用 pmap 分析其中一个进程的 heap 与 anon 占用。
4) 模拟内存占用:运行 stress(若未安装请先安装),观察指标变化。

# Debian/Ubuntu
sudo apt-get install -y stress
# RHEL/CentOS
sudo yum install -y stress

# 启动 2 个进程占用内存 1G
stress --vm 2 --vm-bytes 512M --timeout 60s

# 观察
free -h
vmstat 1 5
top -o %MEM