/proc/<pid>/maps文件格式详解
maps是某个进程的虚拟内存布局,包括代码段、堆、栈、共享库等区域的地址范围、权限和映射来源。
具体说明如下。
文件示例
55f4e7a6a000-55f4e7a6c000 r--p 00000000 08:01 123456 /usr/bin/ls
55f4e7a6c000-55f4e7a71000 r-xp 00002000 08:01 123456 /usr/bin/ls
55f4e7a71000-55f4e7a73000 r--p 00007000 08:01 123456 /usr/bin/ls
55f4e7a73000-55f4e7a74000 rw-p 00009000 08:01 123456 /usr/bin/ls
7f8d4b2a0000-7f8d4b4c0000 rw-p 00000000 00:00 0 [heap]
7f8d4b4c0000-7f8d4b4e5000 r--p 00000000 08:01 789012 /usr/lib/libc-2.33.so
7f8d4b4e5000-7f8d4b63d000 r-xp 00025000 08:01 789012 /usr/lib/libc-2.33.so
7f8d4b63d000-7f8d4b68b000 r--p 0017d000 08:01 789012 /usr/lib/libc-2.33.so
7f8d4b68b000-7f8d4b68f000 rw-p 001cb000 08:01 789012 /usr/lib/libc-2.33.so
7f8d4b68f000-7f8d4b69b000 rw-p 00000000 00:00 0
7ffd3c3e0000-7ffd3c401000 rw-p 00000000 00:00 0 [stack]
7ffd3c5f0000-7ffd3c5f4000 r--p 00000000 00:00 0 [vvar]
7ffd3c5f4000-7ffd3c5f6000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
字段解析(每行 6 列)
每行代表一个 内存映射区域,格式如下:
address perms offset dev inode pathname
字段 | 说明 |
---|---|
address | 虚拟内存的起始和结束地址(16进制,如 55f4e7a6a000-55f4e7a6c000 ) |
perms | 权限标志: • r =可读 • w =可写 • x =可执行 • s =共享 • p =私有(Copy-On-Write) |
offset | 映射文件中的偏移量(16进制),匿名映射为 00000000 |
dev | 设备号(major:minor ),匿名映射为 00:00 |
inode | 映射文件的 inode 号,匿名映射为 0 |
pathname | 映射来源: • 文件路径(如 /usr/bin/ls )• 特殊标记(如 [heap] 、[stack] 、[vdso] ) |
常见内存区域标记
标记 | 说明 |
---|---|
[heap] | 进程的动态堆区域(通过 malloc 分配) |
[stack] | 主线程的栈空间(多线程时其他线程栈不显示在此) |
[vdso] | 虚拟动态共享对象(内核提供的加速系统调用的代码) |
[vvar] | 内核与用户空间共享的数据(如系统时间) |
[vsyscall] | 旧版系统调用兼容区域(64 位系统已弃用) |
[anon] | 匿名映射(如 mmap 分配的私有内存) |
[shmem] | 共享内存(如 tmpfs 或 shmget 分配) |
权限标志详解
r--p
:只读、私有(如代码段的只读部分)。rw-p
:可读可写、私有(如 BSS 段或堆)。r-xp
:可读可执行、私有(如代码段的可执行部分)。rwxs
:可读可写可执行、共享(罕见,可能为 JIT 代码)。
关键场景分析
1. 可执行文件映射
55f4e7a6a000-55f4e7a6c000 r--p 00000000 08:01 123456 /usr/bin/ls
r--p
:只读的代码段(如 ELF 头部)。r-xp
:可执行代码段(.text
段)。rw-p
:可读写的全局变量(.data
或.bss
段)。
2. 动态链接库映射
7f8d4b4c0000-7f8d4b4e5000 r--p 00000000 08:01 789012 /usr/lib/libc-2.33.so
- 共享库被分段映射(只读数据、代码段、读写数据)。
3. 匿名内存区域
7f8d4b68f000-7f8d4b69b000 rw-p 00000000 00:00 0
- 无文件关联(如
mmap
匿名分配的内存)。
工具辅助分析
1. 按权限过滤
# 查找所有可执行的内存区域
grep 'r-x' /proc/<pid>/maps
2. 统计内存占用
# 计算堆内存总大小
grep '\[heap\]' /proc/<pid>/maps | awk '{print $1}' | \awk -F '-' '{sum += strtonum("0x"$2) - strtonum("0x"$1)} END {print sum}'
3. 结合 pmap
命令
pmap -x <pid> # 显示更友好的内存布局摘要
常见问题
Q1: 为什么某些区域的 inode
为 0?
- 匿名映射(如堆、栈)、特殊内核区域(如
[vdso]
)无关联文件。
Q2: 如何确定内存泄漏的区域?
- 检查
[heap]
或匿名映射区域是否异常增长(对比多次maps
快照)。
Q3: 共享库的 offset
非零?
- 动态库被分段加载,
offset
表示该段在文件中的偏移量。
总结
/proc/<pid>/maps
是分析进程内存行为的核心工具。- 字段顺序:
address perms offset dev inode pathname
。 - 权限标志:
rwxp
组合 +s
(共享)/p
(私有)。 - 特殊标记:
[heap]
、[stack]
、[vdso]
等需重点关注。