先说几个核心判断:手动清理 Linux 内存缓存这个操作本身并不复杂,但绝大多数人都在错误的时间、用错误的方式去执行。只要能避开下面这几个最常见的误区,问题就迎刃而解了。

执行 sync 之前别急着写 drop_caches
直接 echo 3 > /proc/sys/vm/drop_caches 会导致数据丢失,这可不是开玩笑的。Linux 的 buff/cache 里很可能还藏着尚未刷盘的“脏页”——比如刚写完但还没落盘的日志、数据库临时文件。不先同步就直接清空,风险等同于拔硬盘前没点“安全弹出”。
正确的做法是:先跑 sync,而且建议连续执行三次:sync; sync; sync。这不是玄学,内核有时会把部分写操作延迟排队,多跑几遍能更大程度确保所有缓冲区真正落盘。
一个很典型的错误案例:free -m 显示 buff/cache 确实下降了,但之后发现文件损坏,或者 MySQL 报出 InnoDB: Database page corruption。排查到最后,大概率就是漏了 sync,或者只跑了一次。
echo 1、echo 2、echo 3 到底该选哪个
值不是越大越好,关键看你想解决什么问题:
echo 1:只清页缓存(PageCache)。适合刚批量读完大文件、想腾出内存给新进程用的场景,同时希望保留目录结构,加速后续的ls或open()操作。echo 2:只清dentries和inodes缓存。对频繁创建/删除小文件的场景(比如日志轮转)有用,但不会影响文件内容的读取速度。echo 3:三者全清,相当于1+2。多数人图省事直接用这个,但代价是下次ls /var/log或打开任意文件都会变慢——内核得重新解析路径、加载 inode。
生产环境下的建议:优先尝试 echo 1,确认无效再升级到 3。不要一上来就用 3,尤其是在数据库或 NFS 挂载点附近操作时。
定时脚本里别裸写 echo 3
自动清理的逻辑不能只看 free 命令输出的 free 字段——它不包含 buff/cache。真正可用的内存是 available 列(CentOS 7.4+ 的 free 默认会显示),或者手动计算 free + buffers + cached。
一个典型错误脚本:只判断 free < 100MB 就触发清理,结果 available 还有 1.2GB,硬清导致服务响应延迟出现 spikes。
推荐的条件判断逻辑:
- 先取
available值:avail=$(free -m | awk 'NR==2 {print $7}') - 设阈值(比如 500MB):
if [ "$avail" -le 500 ]; then ... - 执行前加
sleep 2,避免和其他 I/O 密集任务撞车
crontab 的写法也需要留意:/etc/crontab 必须带用户名(如 root),而 crontab -e 则不能写用户名,写错了就会静默失败。
清完缓存后 echo 0 不生效是正常的
/proc/sys/vm/drop_caches 本质上是一个“开关”,不是配置项。写 3 是发指令,写 0 并不会“关掉机制”——内核压根不支持回写 0,会报 Invalid argument。这跟系统是否重启无关。
它的值只是上次操作的残留记录,不影响后续行为。不用管它,系统照常自动管理缓存。强行 echo 0 只会让运维误以为“已恢复默认”,反而忽略真正的问题——比如某个 Java 进程泄漏了堆外内存,或者 rsync 没关导致持续缓存占用。
最该盯的指标是 available 和 swap 使用率。如果清完缓存后 available 没涨、swap 在涨,那说明不是缓存问题,是程序真的缺内存。
