什么是 /dev/shm
/dev/shm 是开机自动挂载的 tmpfs,页面驻留在内存(紧张时可换出到 swap),不是磁盘文件系统。用 shm_open()、mmap(MAP_SHARED) 或 POSIX 共享内存建立的对象默认就落在这里,Python multiprocessing、PostgreSQL、Chrome 等都依赖它做进程间数据交换。System V 共享内存段(shmget)是另一套机制,不占这个挂载点,由 kernel.shmmax/shmmni 约束。
基本信息
| 文件系统类型 | tmpfs(内存 + swap 承载) |
|---|---|
| 默认挂载点 | /dev/shm,权限 1777(sticky) |
| 默认容量 | 多数发行版为物理内存的一半 |
| 容器内默认 | Docker 为 64MB,可 --shm-size 调整 |
| 相关参数 | kernel.shmmax、kernel.shmmni(System V 侧) |
典型使用场景
- 多进程/多线程服务共享大块数据:Python multiprocessing 的共享数组、Gunicorn 预加载后的写时复制
- 数据库的共享缓冲与并行 worker:PostgreSQL 的并行查询进程、Oracle 的 /dev/shm 用途
- 浏览器与桌面应用:Chrome 用 /dev/shm 做渲染进程的帧缓冲,容器里太小会直接崩页
- 临时中转大文件:需要频繁读写的中间产物放这里比落磁盘快,但重启即丢
- 压测与基准:用 tmpfs 排除磁盘因素,单独衡量 CPU 与网络对处理链路的限制
查看与清理
查看与清理
df -h /dev/shm # 看容量与已用,容器内常见 64M
findmnt /dev/shm # 确认挂载类型与挂载选项
ipcs -m # 列 System V 共享内存段(nattch=0 即无人附着)
ipcs -lm | tail -8 # 看 shmmax/shmmni 等系统限制
ls -lh /dev/shm # POSIX 共享内存对象会以文件形式出现
ipcrm -m <shmid> # 确认归属后清理残留段现象对照速查
| 现象 | 含义 | 处置 |
|---|---|---|
| 容器内 df -h /dev/shm 显示 64M | Docker 默认共享内存上限 | 启动加 --shm-size=1g 或 compose 写 shm_size |
| Shmem 增长但进程 RSS 不变 | 共享内存/匿名页增加 | 查 ipcs -m 与 /proc/*/maps 定位持有者 |
| ipcs -m 有 nattch=0 的段 | 进程异常退出未释放 | 确认无人在用后 ipcrm 删除 |
Kubernetes 里要改共享内存大小,用 emptyDir: {medium: Memory, sizeLimit: 1Gi} 挂到 /dev/shm,不能只改容器镜像内的挂载。
往 /dev/shm 写大文件等于按字节吃掉内存,写满后会触发内存回收甚至 OOM;tmpfs 上占用的 Shmem 属于不可回收部分。
两类共享内存的限制要分开看:/dev/shm 的容量由 tmpfs 挂载 size 决定;System V 共享内存段不够用时查 kernel.shmmax(单段上限)、shmall(总页数上限)、shmmni(段数量上限),老中间件与数据库报 Cannot allocate memory 多与这组参数有关。