C++ 如何实时监控当前进程的内存缺页中断(Page Faults)频率【实战】

千瑶小哥_9000

千瑶小哥_9000

2026-05-26

923人浏览

原创

linux下可通过/proc/[pid]/stat第10、12字段读取minor/major缺页中断次数,需用stringstream+ignore跳过前9字段;监控时须用clock_monotonic计算纳秒级间隔并用nanosleep精准休眠。

c++ 如何实时监控当前进程的内存缺页中断(page faults)频率【实战】

Linux 下用 /proc/[pid]/stat 解析 minor/major page faults

Linux 内核把每个进程的缺页中断次数直接暴露在 /proc/[pid]/stat 的第 10(minor fault)、第 12(major fault)字段里,无需 root 权限,也不依赖 perf 或 ptrace。关键是要知道字段索引从 1 开始、空格分隔、且字段内容可能含空格(比如进程名在第 2 字段),所以不能简单按空格切片。

实操建议:

  • 用 std::ifstream 逐行读取 /proc/self/stat,再用 std::stringstream + ignore() 跳过前 9 个字段(跳过进程名等变长部分),再读第 10 和第 12 个整数
  • 注意:minor fault 是 soft page fault(如 COW、未映射但可分配),major fault 是 hard page fault(需磁盘 I/O,如 mmap 文件首次访问)
  • 字段顺序固定,但内核版本 ≥ 2.6.22 后才保证第 10/12 位稳定;老版本建议 fallback 到 /proc/[pid]/status 中的 MinorPageFaults/MajorPageFaults 行(更易解析但更新频率略低)

用 clock_gettime(CLOCK_MONOTONIC) 做高精度时间差计算

监控频率本质是「单位时间内的增量」,必须用单调时钟测间隔,否则 gettimeofday() 在 NTP 调整或系统休眠时会回跳,导致负的 fault rate 或尖刺假象。

实操建议:

  • 每次采样前调用 clock_gettime(CLOCK_MONOTONIC, &ts),用 ts.tv_sec * 1e9 + ts.tv_nsec 换算成纳秒整数,避免浮点误差累积
  • 两次采样间隔建议 ≥ 100ms:太短则统计噪声大(尤其 minor fault 可能每毫秒上百次),太长则丢失突发峰值
  • 不要用 std::chrono::steady_clock::now() —— 它在某些 glibc 实现中底层仍走 gettimeofday(),不如直接调 clock_gettime 可控

避免轮询阻塞主线程:用 std::thread + 精确 sleep

实时监控不能卡住业务逻辑,但 std::this_thread::sleep_for() 的实际休眠时间常比指定值长(调度延迟 + 时钟粒度),导致采样间隔漂移,fault rate 计算失真。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

实操建议:

  • 在监控线程里用 clock_gettime(CLOCK_MONOTONIC) 记录「期望下次采样时间点」,每次循环末用 nanosleep() 补足剩余时间,而非固定 sleep
  • 示例逻辑:
    auto next = now + interval_ns;<br>while ((now = get_monotonic_ns())     struct timespec req = {0, std::max(1L, next - now)};<br>    nanosleep(&req, nullptr);<br>}
  • 避免用 usleep():其参数是微秒,且在 glibc 中已标记为废弃,精度和可靠性不如 nanosleep()

注意 mmap(MAP_POPULATE) 和 mlock() 对 major fault 的抑制效果

如果你在测试中发现 major fault 频率异常低,不是监控失效,很可能是程序自己做了预加载或锁页——这两者会把 major fault 提前到初始化阶段,运行时就看不到了。

实操建议:

  • 验证是否启用:cat /proc/[pid]/maps | grep -E "(mmapped|locked)" 查是否有 map_lock 标记,或检查代码中是否调用了 mlock() / mmap(... | MAP_POPULATE)
  • MAP_POPULATE 仅对匿名映射无效(只对文件映射生效),而 mlock() 有 RLIMIT_MEMLOCK 限制,超限会失败并返回 ENOMEM
  • 若要真实观察运行时缺页行为,临时注释掉这些调用,或改用 madvise(..., MADV_DONTNEED) 主动丢弃页,再触发访问

监控本身不增加缺页,但读 /proc/[pid]/stat 会引发极少量 minor fault(内核需构造 stat 缓冲区)。真正难处理的是 major fault 的不可预测性——它取决于物理内存压力、swap 状态、甚至其他进程的行为。别指望靠这个数字做绝对性能判断,重点看趋势突变和横向对比。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2228

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1019

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

427

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

406

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

580

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1409

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1217

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习