用pidstat -p PID -r 1实时观察RSS和majflt/s:RSS持续增长且majflt/s低,多为应用主动申请内存;若两者同步飙升,需警惕内存不足或mmap异常;结合-H、-w、-t及smaps_rollup等进一步排查。

直接用 pidstat -p PID -r 1 实时观察目标进程的 RSS 和缺页行为,再结合趋势和上下文交叉判断——内存上涨本身不等于泄漏,关键看 RSS 是否持续增长、是否伴随大量 majflt、是否与应用行为匹配。
盯住 RSS 和缺页指标
内存占用持续上涨,最核心要看两个字段:
- RSS(Resident Set Size):当前驻留在物理内存中的字节数(单位 KB),是真正“吃掉”内存的部分;
- majflt/s(Major Page Faults per second):每秒从磁盘加载页的次数,高值往往意味着内存不足或工作集过大,触发频繁 swap 或文件映射。
命令示例:pidstat -p 1234 -r 1
输出中重点关注 RSS 列是否逐秒递增,以及 majflt/s 是否稳定在高位(比如 >10)。如果 RSS 持续涨而 majflt/s 很低,更可能是应用主动申请内存(如缓存、大对象);如果两者同步飙升,要警惕物理内存不足或 mmap 映射异常。
排除 mmap 和大页干扰
RSS 突然跳涨但进程没报错,常见原因不是泄漏,而是:
- 进程调用了
mmap(MAP_ANONYMOUS)或加载了大文件映射; - 启用了透明大页(THP),导致内核将多个小页合并为 2MB 大页,RSS 统计虚高;
- JVM 类加载、Golang runtime 内存预分配等“合法吃内存”行为。
验证方法:
运行 pidstat -p 1234 -r -H 1(-H 开启高精度时间戳),观察 RSS 变化节奏;再查 /proc/1234/status 中的 MMUPageSize 和 MMUPageSize 字段,若显示 2097152(即 2MB),基本确认是 THP 导致。
联动排查上下文与线程行为
单看内存不够,需叠加其他维度确认是否异常:
- 加
-w查非自愿切换:pidstat -p 1234 -r -w 1,若nvcswch/s(非自愿切换)同步上升,说明可能因内存争抢导致调度延迟; - 加
-t展开线程:pidstat -p 1234 -r -t 1,看是主线程还是某个 worker 线程 RSS 异常增长; - 配合
cat /proc/1234/smaps_rollup查MMUPageSize、Anonymous、FileMapped等细分项,区分是堆内存、mmap 还是共享库占用。
快速定位可疑进程并持续追踪
别靠 ps aux | grep 手动找 PID,容易漏或多实例错位:
- 用
pgrep -f 'java MyApp'或pgrep -u $USER python动态获取 PID; - 组合使用:
pidstat -p "$(pgrep -f 'node server.js')" -r 2,每 2 秒刷新一次; - 想长期观察,可重定向输出:
pidstat -p 1234 -r 5 >> mem.log 2>&1,再用脚本分析趋势。
不复杂但容易忽略。


















