必须用pmap -x PID才能获取每段的起始地址和RSS(实际驻留物理内存KB),默认pmap仅显示地址和映射路径,无法判断真实内存占用;输出含Address、Kbytes、RSS、Dirty、Mode、Mapping六列,其中RSS总和≈进程实际物理内存占用,且可定位堆、数据段、匿名映射等具体内存段。

直接用 pmap -x 查地址+物理内存占用,别信默认输出
不加 -x 的 pmap 只显示十六进制地址和映射路径,根本看不到哪段占了多少物理内存。你真正要的是每段的 RSS(驻留物理内存)和起始地址,这只有 pmap -x <pid></pid> 能给全。
常见错误是跑 pmap 12345 然后对着一串地址发呆——它没告诉你这些地址里有多少页真正在 RAM 里,更没法区分哪些是堆、哪些是共享库的数据段。
-
pmap -x输出固定六列:Address(起始虚拟地址)、Kbytes(总大小)、RSS(真实占用的物理内存 KB)、Dirty(写过但未刷盘的页)、Mode(权限如rw-p)、Mapping(来源) -
RSS总和 ≈ 进程当前实际占的物理内存,和ps -o rss= -p <pid></pid>基本一致,但能拆到每一段 - 地址列(
Address)是十六进制,可直接喂给gdb attach <pid></pid>后用x/10xw 0x56442a9b7000查内容
Mapping 列怎么快速分清堆、数据段、匿名映射
Mapping 不是标签,是内核记录的映射来源,得结合 Mode 和上下文判断:
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
-
[heap]:一定是brk扩展的堆区,Mode是rw-p,RSS持续涨就是 malloc/free 不匹配 -
[anon]:泛指所有无文件 backing 的映射,包括大块malloc(走mmap)、线程栈、JVM DirectBuffer;多个小[anon]RSS加起来很大,说明 native 层分配失控 - 带路径的行(如
/usr/bin/python3.10)且Mode是rw-p:这就是 ELF 的.data和.bss段,RSS就是它当前占的物理内存 -
[stack]或[stack:12345]:主线程或某线程栈,通常RSS在 1–8MB,暴涨说明栈溢出或递归过深
为什么 /proc/<pid>/smaps</pid> 比 pmap -x 更准
pmap -x 的 RSS 是各段简单相加,而 /proc/<pid>/smaps</pid> 对每个 VMA 单独统计,并拆开共享内存摊销——这才是“单进程真实开销”的依据。
- 盯住三列:
Rss(同pmap -x的 RSS 总和)、Pss(共享内存均摊后值,排查整机内存压力必看)、Private_Dirty(泄漏最硬指标,持续增长 = 进程自己在 malloc + 写入没 free) - 查堆段:
grep -A 5 "heap" /proc/<pid>/smaps</pid>,看Private_Dirty是否异常高 - 查数据段:
awk '/^Name:/ && /data/ { getline; print }' /proc/<pid>/smaps</pid>,过滤出 .data/.bss 相关行 - 注意:
smaps行数可能上千,别用cat直接读,必须配合grep或awk定向提取
pmap -d 是假选项,别浪费时间试
主流 Linux 发行版(Ubuntu/CentOS/Debian)的 pmap 不支持 -d。执行 pmap -d <pid></pid> 会报 invalid option -- 'd' 或直接显示帮助页。
- 你想要的“设备与偏移”信息,其实藏在
/proc/<pid>/maps</pid>原始输出里:第五列是mj:mn(主次设备号),第六列是inode,第七列是文件路径 - 想确认某段是不是纯匿名:
cat /proc/<pid>/maps | awk '$5 == "00:00" && $7 == "" {print}'</pid>,设备号00:00且无路径 = 真·匿名映射 - 所有需要深度分析的场景,正确路径是:
pmap -x <pid></pid>快速定位 →/proc/<pid>/smaps</pid>验证Private_Dirty→ 必要时回溯/proc/<pid>/maps</pid>看原始权限和设备字段
地址映射本身是确定的,但物理页是否真在 RAM 里、是否被共享、是否被写过——这些细节全靠 RSS、Pss、Private_Dirty 这三列交叉验证,漏掉任意一个都可能把共享库误判成泄漏源。

















