为何pmap显示共享内存为8K?实际总大小仅2048字节
问题解答
是分页机制结合System V共享内存的设计特性导致的,核心原因在于每个System V共享内存段会被独立分配并映射到完整的页,具体解释如下:
1. 分页机制的基础约束
你的系统页大小为4096字节,内核对内存的分配和映射都是以页为最小单位——任何内存区域的起始地址必须对齐到页边界,且占用的虚拟内存空间会向上取整到页的倍数。但这只是基础条件,不是两个1K段无法合并到一页的核心原因。
2. System V共享内存的段独立性设计
System V共享内存采用段式管理模型:
- 每个共享内存段是独立的内核对象,拥有专属元数据(权限、大小、关联进程列表等),对应内核中的
struct shmid_kernel结构。 - 内核会为每个段单独分配物理页,在进程地址空间映射时,强制给每个段分配完整的虚拟页——哪怕段实际大小远小于页大小。
也就是说,哪怕你创建的是1024字节的段,内核也会为它分配一整个4K的物理页,并且在进程虚拟地址空间中占据一个4K的连续区域。两个这样的段自然会占用2×4K=8K的虚拟内存空间,这就是pmap统计值为8K的原因。
3. 为何不能合并到单个页?
System V共享内存的设计目标是支持独立生命周期管理:
- 每个段可以被单独挂载、卸载、销毁,权限也是针对单个段设置的。如果把多个小合并到同一个页,当其中一个段被销毁时,内核无法只释放页中的一部分,会导致内存管理复杂度飙升。
- 内核处理共享内存映射时,每个段对应独立的页表条目,这些条目关联的是整个页的物理内存,无法拆分页来对应多个段。
验证方式
你可以通过以下命令确认:
- 执行
ipcs -m查看每个共享内存段的配置,能看到每个段的大小确实是1024字节; - 执行
pmap -x <pid>查看详细虚拟内存映射,会发现两个共享内存段对应的虚拟地址范围都是4K的整数倍,每个范围的大小都是4096字节。
内容的提问来源于stack exchange,提问作者Soumajit
相关产品推荐
相关产品推荐

