ipcs -m 无法显示具体进程PID,仅提供nattch(附加进程数);要定位使用某shmid的进程,须执行grep -r "shmid=XXX" /proc/[0-9]*/maps 2>/dev/null。

ipcs -m 能看到共享内存,但看不到哪个进程在用
直接运行 ipcs -m 只显示系统级共享内存段的 key、shmid、owner、bytes、nattch 等字段,其中 nattch 是当前附加(attached)的进程数,但它不列出具体 PID。这意味着你无法单靠这个命令知道是哪些进程正在使用某段共享内存。
真正能关联进程与共享内存的方式是查 /proc/[pid]/maps 或 /proc/[pid]/smaps:
-
cat /proc/[pid]/maps | grep "shmid"—— 如果该进程通过shmget+shmat方式使用 XSI 共享内存,maps中通常不会出现 shmid 字样;但若使用mmap映射匿名或文件-backed 内存,则可能看到rw-s-标志和00000000偏移,需结合smaps判断是否为共享映射 -
cat /proc/[pid]/smaps | grep -E "^(MMU|Shmem|Rss|Pss|Size):"—— 关键看Shmem:行,非零值说明该进程有共享内存页(包括 tmpfs、shm 文件、mmap SHARED 区域) - 对 POSIX 共享内存(
/dev/shm/xxx),可直接lsof +D /dev/shm查打开该文件的进程
为什么 ps aux --sort=-rss 里看不到共享内存的真实开销
ps 的 RSS(常驻内存集)会把共享内存页重复计入每个使用它的进程 —— 比如一段 64MB 的共享内存被 10 个进程 attach,ps 会显示每个进程 RSS 都 +64MB,总和虚高,但这不是真实物理内存占用。
真正反映共享内存“摊薄后”成本的是 PSS(Proportional Set Size),它把共享页大小除以使用它的进程数再累加。要获取这个值,必须用 smem:
-
smem -s pss -r按 PSS 降序列出所有进程(需要提前安装smem) -
smem -P your_process_name -c "pid comm pss rss uss"查指定进程的内存构成 - 注意:
USS(Unique Set Size)才是真正独占的物理内存,PSS = USS + (共享页大小 / 使用进程数)
如果只依赖 top 或 ps 排序 RSS,很容易误判某个进程“吃内存”,实际只是共享内存的“挂名使用者”。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
共享内存泄漏:shmid 一直存在但 nattch=0 却删不掉
运行 ipcs -m 发现某段共享内存 nattch=0,但 ipcrm -m shmid 报错 Operation not permitted 或直接失败,常见原因有两个:
- 该段共享内存被标记为“dest”(destroyed),即创建者调用了
shmctl(shmid, IPC_RMID, ...),但仍有进程未 detach —— 此时内核已标记待销毁,但物理内存不会释放,直到所有进程 detach。此时ipcs -m显示status列为dest,nattch可能为 0 或 >0,但不能强制删除 - 权限问题:
ipcrm必须由共享内存 owner 或 root 执行;普通用户无法删除别人创建的段,即使nattch=0
验证是否真有残留 attach:用 grep -r shmid /proc/[0-9]*/maps 2>/dev/null(替换 shmid 为十进制 ID)快速扫一遍所有进程 maps,看是否有匹配行。若有,说明还有进程没 detach,得找对应 PID 去处理。
POSIX vs XSI 共享内存,排查命令完全不同
Linux 有两套主流共享内存机制,底层行为和排查方式差异很大:
- XSI 共享内存(
shmget/shmat):走内核 IPC 设施,ipcs -m和ipcrm -m有效,资源在/proc/sys/kernel/shmmax等参数限制下管理 - POSIX 共享内存(
shm_open/mmap):本质是基于/dev/shm的 tmpfs 文件,ipcs完全不可见;得用ls -l /dev/shm、find /dev/shm -name "*pattern*" -ls、lsof +D /dev/shm查
混淆这两者是定位失败的最常见原因。比如你用 ipcs -m 查不到某段“共享内存”,不代表它不存在 —— 很可能它是 shm_open("/myshm", ...) 创建的,正躺在 /dev/shm/myshm 里。这时候删错地方,问题只会更隐蔽。

















