tmpfs 与内存的关系
tmpfs 是基于内存的文件系统,其中的文件直接消耗物理内存并计入 /proc/meminfo 的 Shmem。排查占用要分三层看:df -h 看挂载点用量与容量上限、du 与 lsof 找具体文件、meminfo 的 Shmem 看全局总量。容器环境里 /dev/shm 与 /tmp 是高发区。特别要注意:tmpfs 占用的页不会被 drop_caches 释放,只有删除文件(或换出)才能真正归还内存。
基本信息
| 查看用量 | df -h /dev/shm /tmp |
|---|---|
| 内存口径 | /proc/meminfo 的 Shmem;容器内看 memory.stat 的 shmem |
| 默认容量 | 通常为物理内存的一半(依发行版与配置而定) |
| 容量限制 | 挂载参数 size=、nr_inodes=,可用 remount 调整 |
| 释放方式 | 删除文件或卸载;drop_caches 无效 |
| 可换出性 | shmem 页可以被换出到 swap |
典型使用场景
- 容器内存无故增长:检查 /dev/shm 里是否留有大文件
- 应用用 /dev/shm 做共享内存缓存但未清理,长期累积
- /tmp 被当作临时存储写满,间接吃掉大量内存
- 核查 df 与 meminfo:tmpfs 占用只记在内存、不计入磁盘容量
- 为容器调整 /dev/shm 容量,避免默认值过小导致业务失败
排查步骤
排查步骤
df -h /dev/shm /tmp # 看 tmpfs 的容量上限与已用量
grep -E '^Shmem' /proc/meminfo # 全局 tmpfs 占用总量
grep -E '^shmem ' /sys/fs/cgroup/myapp.slice/memory.stat # 容器视角的 tmpfs 占用
sudo du -sh /dev/shm/* 2>/dev/null | sort -h | tail # 找出占用最大的文件
sudo lsof +D /dev/shm | head # 确认文件是否仍被进程持有(已删除但未释放)
sudo mount -o remount,size=256M /dev/shm # 调小上限,注意已用超过新值时会被拒绝查看入口对照
| 查看项 | 入口 | 说明 |
|---|---|---|
| 挂载点用量 | df -h /dev/shm /tmp | 含容量上限与已用量 |
| 全局总量 | /proc/meminfo 的 Shmem | 所有 tmpfs 挂载的合计 |
| 容器占用 | memory.stat 的 shmem | 该 cgroup 内的 tmpfs 占用 |
| 具体文件 | du + lsof | 定位大文件与已删除但被持有的文件 |
删除文件后内存不一定立刻归还:只要还有进程持有文件句柄,容量就仍被占用。这种情况下要用 lsof 找到持有者,重启或关闭对应进程才能释放。
容器运行时通常给 /dev/shm 设置较小的默认容量(常见 64MB 量级),需要更大共享内存的应用必须通过运行时参数显式调大,否则会写入失败而不是单纯变慢。