linux-sre-handbook

02-内存性能分析

内存指标速查

指标 工具 含义
总内存 / 已用 / 可用 free -h 物理内存使用概览
RSS pmap / top 进程实际物理内存
VSZ pmap / top 虚拟内存大小
PSS smem 按共享比例分摊的内存
缺页 (Page Fault) pidstat -r 每秒缺页次数
Swap 使用 free -h, vmstat 匿名页换出量

工具链

1. 总览

free -h                # 内存 + Swap 概览
vmstat 1               # si/so: swap in/out
sar -r 1              # 内存使用历史
sar -B 1              # 缺页统计

2. 进程级

ps aux --sort=-%mem | head     # 按内存排序
top -o %MEM                    # top 按内存排序
pmap -x <PID>                  # 进程内存映射详情
smem -p                        # 按 PSS 计算内存

3. 深入分析

cat /proc/meminfo              # 详细内存信息
cat /proc/<PID>/smaps          # 进程内存段详情
cat /proc/<PID>/status | grep Vm  # 进程内存摘要
cat /proc/buddyinfo            # Buddy 分配器状态
cat /proc/slabinfo             # Slab 缓存状态
slabtop                        # Slab 实时排序

/proc/meminfo 关键解读

MemTotal:     16384000 kB    # 总物理内存
MemFree:       2048000 kB    # 完全空闲(不含缓存)
MemAvailable:  8192000 kB    # 可用(含可回收缓存)
Buffers:        512000 kB    # 块设备缓冲
Cached:        4096000 kB    # Page Cache
SwapTotal:     4096000 kB
Dirty:            128 kB    # 待回写的脏页
Writeback:          0 kB    # 正在回写的页
AnonPages:     2048000 kB    # 匿名页

内存泄漏排查

# 1. 监控进程内存增长趋势
while true; do
    ps -o rss= -p <PID> >> mem.log
    sleep 60
done

# 2. 堆分析
gdb -p <PID>                          # 附加进程
call malloc_stats()                    # 查看 malloc 统计

# 3. 使用 Valgrind(开发环境)
valgrind --leak-check=full ./myapp

OOM 排查

dmesg | grep -i oom                  # 系统日志中的 OOM 事件
cat /proc/<PID>/oom_score            # 当前 OOM 评分
echo -1000 > /proc/<PID>/oom_score_adj  # 豁免 OOM

# OOM 日志解读要点:
# - 被杀进程名和 PID
# - 当时的 /proc/meminfo 快照
# - 各进程的内存使用排名

内存决策树

内存问题?
├─ OOM / 内存泄漏 → 监控 RSS 趋势 → gdb/valgrind 定位
├─ 系统内存高但可用少 → 检查 Cached/Buffers → 可回收
├─ Swap 使用高 → 降低 swappiness → 扩内存
├─ 频繁缺页 → 内存不足或访问模式差 → 优化代码
└─ Slab 占用高 → slabtop 定位 → 排查内核对象泄漏

延伸阅读