缺页异常
解读你当前的结果
-
CPU 利用率:
116,526.68 msec cpu-clock/14.5666 s elapsed= 8.0 CPUs 利用率
→ 说明这台机器至少 8 核,期间所有 CPU 几乎满载。 -
上下文切换:
305,564 context-switches,平均 20.9K/s,不算特别高。 -
CPU 迁移:
31,105 cpu-migrations,约 2.1K/s,稍微偏高,说明 scheduler 在频繁搬运进程。 -
缺页异常:
34,784 page-faults,约 2.3K/s,正常范围(主要是 minor faults)。
→ 总体看,没有 cycles/instructions 数据,无法计算 IPC/CPI,但能看出系统确实在高负载运行。
Linux 中的缺页异常(Page Fault)
1. 概念
在 Linux(以及其他现代操作系统)里,进程访问虚拟内存时,必须先有页表把虚拟地址映射到物理内存页。
如果访问的虚拟地址 没有映射,CPU 会触发 缺页异常(page fault),交给内核处理。
2. 缺页异常的分类
| 类型 | 触发场景 | 是否涉及磁盘 I/O | 开销 | 典型场景 |
|---|---|---|---|---|
| Minor Page Fault(次缺页异常) | 页已经在内存中,但页表条目未建立(如 mmap 第一次访问、共享库、COW 写时复制) | ❌ 不涉及 | 纳秒 ~ 微秒级 | 程序启动加载库、fork 后第一次写入内存 |
| Major Page Fault(主缺页异常) | 页不在内存,需要从磁盘或 swap 加载 | ✅ 涉及 | 毫秒级甚至更高 | 内存不足触发 swap、访问大文件映射 |
3. perf 统计中的 page-faults
在 perf stat 中,你看到的:
34,784 page-faults
其实是 minor + major 的总数。
要拆开看,可以用:
perf stat -e minor-faults,major-faults -a sleep 5
4. pidstat 中的 minflt/s 和 majflt/s
如果要分析进程级别,可以用:
pidstat -r -p <pid> 1
输出中会有:
-
minflt/s= 每秒 minor faults-
页已经在内存中,只需更新页表,代价低。
-
-
majflt/s= 每秒 major faults-
页需要从磁盘加载,代价高。
-
示例:
# minflt/s majflt/s
1234 1200.0 0.0 # 进程 1234 每秒 1200 次 minor fault,正常
5678 30.0 8.0 # 进程 5678 每秒 8 次 major fault → 可能涉及 IO/内存不足
5. 如何判断缺页异常是否严重?
-
Minor faults
-
常见且正常,几千/s 甚至几万/s 都可能接受。
-
程序刚启动时会非常多(加载代码段、共享库)。
-
-
Major faults
-
需要重点关注,>100/s 就可能表示:
-
内存压力大(频繁 swap)
-
应用访问了大量未缓存的 mmap 文件
-
IO 吞吐不足
-
-
6. 实际排查方法
-
统计系统范围内的 minor/major
perf stat -e minor-faults,major-faults -a sleep 5 -
查看进程级别缺页异常
pidstat -r 1找出
majflt/s明显高的进程。 -
查看系统是否 swap
vmstat 1-
si(swap in)、so(swap out)非零 → major faults 很可能很多。
-
-
持续监控
sar -B 1-
majflt/s:系统范围的 major faults -
pgpgin/s、pgpgout/s:磁盘读写的页数
-
7. 总结
-
page-faults = minor + major
-
minflt/s= 页在内存里,只是没建页表,成本低 -
majflt/s= 页不在内存,需要磁盘 IO,成本高,需要重点监控 -
你
2.3K/s的缺页异常大概率是 minor,属于正常范围。真正需要担心的是majflt/s是否过高。
👉 要不要我帮你写一个 一键诊断脚本,直接跑出来系统范围和各进程的 minor/major faults 情况,并标红 majflt/s 高的进程?
浙公网安备 33010602011771号