查看和回收 Linux 页缓存,区分缓存、可用内存与内存压力
page cache 是内核为文件内容保留的内存副本:读文件命中缓存时不必访问磁盘,写操作先进入缓存再回写。它属于可回收内存,所以 free 里的 buff/cache 高并不等于内存不足;真正要看的是 MemAvailable、回收扫描计数和 PSI。
/proc/meminfo 的 Cached、Buffers、Dirty、Writeback、MemAvailable;vmstat、sar -r 看趋势。vmtouch(需另行安装)、fincore(util-linux)可查看文件有多少页在缓存中;posix_fadvise(POSIX_FADV_DONTNEED) 可让指定文件的干净页被回收。Cached,但没有磁盘后备,不能靠“回写后丢弃”释放;这部分只能换出或由应用释放。/proc/sys/vm/drop_caches 需要 root,且是全局操作,容器内通常不可写。cachestat,它直接观察内核页缓存事件,而不是看内存总量。# 查看缓存、脏页和真正可用的内存
free -h
grep -E '^(MemAvailable|Cached|Buffers|Dirty|Writeback):' /proc/meminfo
# 查看单个文件有多少内容在 page cache 中
vmtouch -v /var/lib/app/data.bin
# 第一次读与缓存命中的耗时对比(观察 real 时间)
time dd if=/var/lib/app/data.bin of=/dev/null bs=1M count=512
# 让指定文件的干净缓存页被回收(不删除文件)
vmtouch -e /var/lib/app/data.bin
# 查看文件实际占用的缓存页(较新的 util-linux 提供 fincore)
fincore /var/lib/app/data.bin
# 清理干净页缓存和可回收 slab:仅用于测试/基准,不要在生产例行执行
sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
O_DIRECT 读写会绕过 page cache,适合数据库等自行管理缓存的场景,但要求缓冲区地址、长度和文件偏移按设备逻辑块对齐。
free 很小就判定内存不足是误判;page cache 会在压力下自动回收,先看 MemAvailable 和 si/so。drop_caches 只回收干净页;脏页必须先回写,所以执行后 Cached 不会立刻降到预期。echo 3 > drop_caches 还会丢掉 dentry/inode 等可回收 slab,短时间大量 stat/open 会变慢;不要把它当作日常“释放内存”手段。Cached,没有磁盘后备,不能通过 drop_caches 释放;容器里写满 tmpfs 会直接消耗内存额度。memory.max 时可能先回收缓存再 OOM;在 memory.stat 里看 file、file_dirty、shmem。posix_fadvise(DONTNEED) 只对干净页有效,也不影响其他进程正在使用的映射;不要指望它立即释放脏页。read_ahead_kb 控制,盲目调大在随机读场景会浪费缓存和带宽。free 里 buff/cache 很高,是否意味着需要加内存?drop_caches 后 Cached 没有明显下降?Cached 里,能不能通过 drop_caches 释放?MemAvailable、直接回收计数和 PSI,而不是单看缓存大小。