/dev/shm 的 size 限制由内核默认值(如64mb/512mb)和挂载选项(如size=2g或size=5%)共同决定,非固定值;其内存不自动释放易被误认为泄漏,实为配置与使用不当所致。

tmpfs 的 size 限制由内核参数和挂载选项共同决定,不是固定值;/dev/shm 默认受 tmpfs 总大小约束,不当使用确实可能引发内存耗尽,但本质是配置与使用方式问题,而非 inherent 内存泄漏。
size 限制从哪来?
/dev/shm 是 tmpfs 类型的虚拟文件系统,其大小上限取决于两个层面:
- 内核默认限制:早期内核(如 RHEL/CentOS 6)默认 /dev/shm 挂载为 64MB;较新内核(如 RHEL 8+/Ubuntu 20.04+)通常设为 512MB 或 1GB,但实际仍可动态调整
- 挂载参数控制:通过 size= 选项显式指定,例如:
mount -t tmpfs -o size=2G tmpfs /dev/shm
该值可设为字节数(如 2097152000)、带单位(2G、512M),也可用百分比(如 size=5%)表示物理内存比例(需内核 ≥ 5.12 且启用 CONFIG_TMPFS_SIZE_PERCENT) - 全局 tmpfs 上限(较少用):可通过 vm.max_map_count 或 vm.shmall 间接影响,但不直接限制 /dev/shm,主要约束 mmap 区域总数和共享内存页数
为什么看起来像“内存泄漏”?
tmpfs 数据驻留内存(或 swap),但不会自动释放——只要文件被进程打开或硬链接存在,对应内存就不会回收。常见诱因包括:
- 程序创建 shm_open + mmap 后未调用 shm_unlink,且进程异常退出,导致共享内存段残留
- 容器环境(如 Docker)中,/dev/shm 默认仅 64MB,若应用大量使用 POSIX 共享内存(如 TensorFlow、某些数据库驱动),迅速填满后表现为 OOM 或 write failure
- 脚本反复创建命名共享内存但未清理,例如循环中用
shm_open("/mydata", O_CREAT|O_RDWR, 0600)却漏掉shm_unlink - 内核未启用 tmpfs 的自动回收机制(如 noexec,nodev 等不影响,但 nr_inodes 耗尽会导致创建失败,非内存泄漏)
如何主动控制风险?
关键在“可观察 + 可约束 + 可清理”:
-
监控用量:定期检查
df -h /dev/shm和ls -l /dev/shm/;用ipcs -m查 System V 共享内存(注意:POSIX shm 不在此列,需看 /dev/shm 下文件) -
启动时强制限制:在 /etc/fstab 中固化配置,例如:
tmpfs /dev/shm tmpfs defaults,size=1G 0 0
重启或运行mount -o remount /dev/shm生效 -
容器场景适配:Docker 运行时加
--shm-size=2g;Kubernetes Pod 中通过securityContext.sysctls或 volumeMounts 挂载定制 tmpfs -
应用层防御:在 shm_open 后立即 shm_unlink(允许已映射继续访问,但避免残留);使用 RAII 或 defer 保证 cleanup;对关键服务添加启动前清空逻辑(如
find /dev/shm -mindepth 1 -delete 2>/dev/null)
要不要担心 swap 影响?
tmpfs 支持换出到 swap,但行为取决于 vm.swappiness 和可用 swap 空间。若禁用 swap(swappiness=0),tmpfs 将完全驻留物理内存,超限时触发 OOM killer。建议:
- 生产环境保留适量 swap(如 2–4GB),避免因短暂 peak 导致 OOM
- 不依赖 swap 缓解 /dev/shm 压力——应以合理 size 配置 + 应用规范使用为主
- 用
cat /proc/meminfo | grep Shmem查看当前所有 tmpfs 使用总量(含 /dev/shm),比 df 更准确










