内存与 OOM58 条

pmap 进程映射明细

逐段列出进程地址空间的映射与 RSS/Dirty,定位大块匿名映射、文件映射或异常增长段。

什么是 pmap

pmap 把进程的地址空间逐段列出:每一行是一个映射(可执行文件段、共享库、匿名内存、线程栈等),并给出该段的虚拟大小、常驻内存(RSS)与脏页大小;输出末尾还有一行总计。用它可以看出“内存去哪了”:是某个共享库占了大头,还是匿名段(堆、mmap)在持续增长。把 RSS 列排序后取前几行,通常就能定位到可疑的大块映射。

基本信息

查看pmap -x <pid>
扩展格式pmap -X <pid> 提供更多字段(含 PSS 等)
总计行输出末尾的 total 行
映射类型可执行段、共享库、[anon]、[stack]、[heap]
排序技巧用 sort -k3 -rn 按 RSS 列排序
权限查看他人进程需要相应权限

典型使用场景

  • 判断大内存块来自共享库还是匿名映射
  • 排查内存泄漏:观察 [anon] 段的增长
  • 核对线程栈数量:线程多时栈映射会明显增多
  • 确认 JIT 或大页映射是否按预期存在
  • 与 smaps 对比,检查脏页与常驻页的比例关系

常用命令

常用命令
pmap -x 12345 | head -20                 # 逐段查看
pmap -x 12345 | tail -3                  # 总计行
pmap -x 12345 | sort -k3 -rn | head -10  # 按 RSS 列排序找大段
pmap -X 12345 | head -10                 # 扩展字段(含 PSS/Swap 等)
grep -c 'rw-p' /proc/12345/maps          # 粗略统计可读写匿名映射数量
cat /proc/12345/status | grep -i threads # 线程数,与栈映射数量相关

输出逐列读法

列含义判读要点
Address映射起始地址配合范围看段大小
Kbytes虚拟大小包含未实际使用的部分
RSS常驻内存判断真实占用
Dirty脏页大小写入频繁的段会偏高
Mode权限与映射类型区分库、堆、栈与匿名段
映射段数量多不一定是问题:线程栈与 JIT 生成的代码段都会增加映射数,判断依据应是体积与增长趋势,而不是行数。
在内存很大或映射极多的进程上执行 pmap 会遍历大量映射,短时占用不小;排查故障时尽量指定进程并避开高峰。
只关心内存总量与占比时,用 smaps_rollup 或 pmap -X 更省事;pmap -x 的长处是快速看清某一段映射的大小与类型,两者按目的选用。

易错点

  • [anon] 段增长可能来自 malloc 或 mmap,需结合应用日志与堆分析判断,不能只看数字下结论
  • 映射数量多也可能是正常(线程栈、JIT),看体积与增长趋势才是有效判据
  • 把 Kbytes 列当作实际占用:它是虚拟大小,真实占用要看 RSS 列
  • 在大进程上频繁执行 pmap 会带来额外开销,排障窗口内应控制执行频率

数据来源与参考

  • procps-ng 文档 pmap(1)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌