Linux共享内存显示异常求助:fork子进程内存统计不符
1. top命令中父子进程Shared列数值差异的原因
你看到的父进程876K Shared内存,并非你创建的匿名共享内存,而是可执行文件(a.out)的代码段/只读数据段——这部分是所有运行该程序的进程共享的文件映射内存。
而你用MAP_SHARED | MAP_ANONYMOUS创建的匿名共享内存,在top的Shared列统计逻辑中,不会被计入子进程的Shared数值:
- top的Shared列统计的是基于文件的共享内存(比如程序的文本段、动态库、挂载的文件映射);
- 匿名共享内存不属于文件映射,fork后父子进程共享的是匿名页,top不会将这类内存统计到子进程的Shared列中,但实际内存确实是共享的。
从你提供的smaps输出也能看到,匿名共享内存(以/dev/zero (deleted)形式存在,部分系统用/dev/zero模拟匿名映射)的RSS只有4KB,这部分内存不会出现在top的Shared列里。
2. /proc/[pid]/status中RssShmem为0的原因
RssShmem字段统计的是System V共享内存、tmpfs/shmem这类基于文件系统的共享内存,而你创建的MAP_SHARED | MAP_ANONYMOUS匿名共享内存,内核将其归类到RssAnon(匿名内存)范畴,而非Shmem。
看你提供的/proc输出:
RssAnon: 88 kB
RssFile: 876 kB
RssShmem: 0 kB
这里的88KB RssAnon已经包含了你创建的4KB匿名共享内存(剩余部分是进程栈、堆等匿名内存),所以RssShmem为0是完全正常的。
3. 父子进程Shared_Dirty/Shared_Clean数值不一致的原因
smaps中的Shared_Dirty/Shared_Clean是从单个进程的页表视角统计的共享页面状态,而非全局内存状态,数值不一致通常有以下原因:
- 页面访问时机不同:如果其中一个进程还未访问过共享页面,内核不会在该进程的页表中标记页面的共享/脏状态,导致统计数值缺失;
- 内核统计延迟:页面状态的更新(比如脏页标记)可能不会立即同步到所有共享进程的统计数据中;
- 页表映射关联差异:fork后,内核需要在进程页表中完成共享页面的映射关联,若某进程还未触发这个关联动作,其统计数据就不会包含对应页面的状态。
从你的smaps输出看,共享页面的Shared_Dirty是4KB,Pss是2KB——这说明父子进程均分了该共享页面的内存开销,符合共享内存的预期。
代码验证
你的代码没有问题:
- 使用
MAP_SHARED | MAP_ANONYMOUS创建的匿名共享内存,fork后父子进程确实共享同一块物理内存,读写操作会互相可见; - 代码中父子进程的读写逻辑、内存释放流程都符合规范,sleep仅用于观察状态,不影响共享内存的功能。
内容的提问来源于stack exchange,提问作者dejing liu

