发现swap引发响应毛刺的关键是捕捉“内存不足→换页→缺页异常→延迟突增”信号链,重点监控si/so(pages/sec)持续>100或毛刺时跳至上千,结合pgmajfault与pgpgin激增、应用延迟时间戳对齐验证,而非仅看swapused绝对值。

发现 Swap 引起的响应毛刺,关键不是等应用报错,而是提前捕捉内存压力传导到延迟的“信号链”:内存不足 → 触发换页 → 进程阻塞在缺页异常(page fault)→ 响应时间突增。
看 swap 使用量和活动频率
仅看 SwapUsed 绝对值容易误判。重点盯两个动态指标:
-
swapin/s 和 swapout/s(单位:pages/sec):用
vmstat 1或cat /proc/vmstat | grep -E "pgpgin|pgpgout"查。持续 > 100 pages/sec 就值得警惕;毛刺期间若突然跳到上千,基本可锁定 Swap 活动是直接诱因 - si/so 列(vmstat 输出):si(swap-in)> 0 且持续多秒,说明进程正在从磁盘把页读回内存,此时 Redis、Java 等用户态进程会卡在 page fault 上,造成毫秒至秒级延迟
关联延迟毛刺与内存分配行为
Swap 毛刺往往伴随内核级内存申请延迟:
- 查 /proc/$(pgrep redis-server)/stack 或用
perf record -e 'kmem:mm_page_alloc' -p $(pgrep redis-server) -- sleep 10,看是否大量线程停在__alloc_pages_slowpath或wait_on_page_bit - 用
cat /proc/vmstat | grep -E "pgmajfault|pgpgin"对比毛刺前后:如果 pgmajfault(次缺页)激增,同时 pgpgin(换入页数)同步飙升,就是 Swap 导致缺页等待的铁证
结合应用层延迟与系统指标交叉验证
单一指标易误导,需时间戳对齐:
- Redis 场景:用
redis-cli --latency-history记录毛刺发生时刻(如14:22:36.892),立刻查该秒的vmstat 1输出,确认 si/so 是否非零 - JVM 场景:GC 日志中若出现 long STW 且无 Full GC 记录,同时
dmesg -T | grep -i "Out of memory"或"Killed process"为空,但free -h显示可用内存极低 + SwapUsed > 50%,大概率是 JVM 线程被 swap out 后唤醒慢,而非 GC 本身耗时 - 容器环境:
kubectl top pod显示内存使用接近 limit,但docker stats或cgroup v2 memory.current显示实际用量远低于 limit —— 说明被 cgroup 内存回收(包括 swap)压制,而非应用真占满内存
别忽略透明大页(THP)与 Swap 的叠加效应
THP 默认启用(always)时,会加剧 Swap 毛刺:
- 大页分配失败后更容易 fallback 到普通页 + 触发换页
- 用
cat /sys/kernel/mm/transparent_hugepage/enabled确认是否为[always];若毛刺频繁且伴随高 major fault,建议设为never - 同时检查
/sys/kernel/mm/transparent_hugepage/defrag,若为always,其后台规整动作也会争抢内存带宽,放大 Swap 延迟










