内存占满了怎么办?先别重启,按这四步定位并释放
内存占满了先别急着重启。
Linux 会把空闲内存拿去做缓存,free 里 available 还有余量时通常不是故障;
真正要处理的是 available 接近 0、进程持续吃内存或系统已经触发 OOM 的情况。
下面按“确认现状、定位占用、处理释放、验证复查”的顺序说明。
先确认内存是真的不够用
登录服务器后执行:
free -h
top -o %MEM
看 free -h 的 available 列,它比 free 列更能反映应用还能用多少内存。
如果 available 只剩几十 MB 甚至为 0,同时 top 里某个进程的 RES(常驻内存)持续上涨,才需要进一步处理。
还可以用 ps 按内存排序:
ps aux --sort=-%mem | head -n 10
输出里的 RSS 是进程实际占用的物理内存。
先记下占用最高的进程名和 PID,再判断它是正常业务进程还是异常进程。
区分缓存占用和进程占用
free 里的 buff/cache 是内核用来加速磁盘读写的缓存,不是泄漏。
手动清缓存只能临时腾出数字,不能解决应用持续吃内存的问题,也不建议在生产环境频繁执行。
真正要关注的是:
- 某个进程 RES 很高且随时间上涨,可能是内存泄漏或配置不合理。
- 系统日志出现
Out of memory: Killed process,说明已经触发 OOM Killer。 - available 长期低于总内存的 10%,业务可能随时被系统杀掉。
查看 OOM 记录:
dmesg | grep -i 'out of memory'
journalctl -k | grep -i oom
如果看到进程被 kill,先确认被杀的进程是不是核心业务,再决定是限制该进程内存还是增加 swap。
针对高内存进程做处理
定位到具体进程后,按原因处理,不要直接 kill -9 了事。
如果是 Java 服务,检查启动参数里的 -Xmx 是否超过物理内存的合理比例,通常建议堆内存不超过总内存的 50% 到 70%,并留出系统和其他进程空间。
如果是 MySQL,检查 innodb_buffer_pool_size 是否设得过大,这个参数会长期占用大量内存,调整后需要重启 MySQL。
如果是 PHP-FPM 或类似进程池,检查 pm.max_children 是否过多,每个子进程都会占用内存,可以适当调低并观察业务是否正常。
临时释放可以重启对应服务:
systemctl restart 服务名
重启前确认业务允许短暂中断,并保留现场日志。
对不确定的进程,先 kill -15 PID 发送正常终止信号,观察是否自动恢复,不要直接 kill -9。
如果服务器本身内存偏小,可以增加 swap 作为缓冲:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile swap swap defaults 0 0' >> /etc/fstab
swap 只是兜底,不能替代内存扩容,磁盘 IO 慢时反而会拖慢业务。
处理完要复查效果
操作后再次执行:
free -h
ps aux --sort=-%mem | head -n 10
确认 available 恢复到安全范围,高内存进程的 RES 没有继续快速上涨。
如果条件允许,用 vmstat 2 5 观察 si/so 是否持续非零,持续非零说明系统在频繁换页,内存压力仍然存在。
最后把监控补上,至少对 available 和进程内存设置告警,避免下次再靠人工发现。
内存占满了怎么办,核心不是清缓存,而是找到持续吃内存的进程并处理它的配置或代码问题。
常见疑问
清缓存命令能随便用吗?
不建议。echo 3 > /proc/sys/vm/drop_caches 会丢掉磁盘缓存,短时间可能让磁盘 IO 升高,生产环境只在明确需要时执行。
available 还有一点但业务已经卡了,是什么原因?
可能是 swap 使用过多或磁盘 IO 瓶颈,先看 vmstat 的 si/so 和 iostat 的磁盘利用率,不要只盯内存数字。
加了 swap 是不是就不用扩内存了?
不是。swap 在物理内存不足时提供缓冲,频繁换页会明显降低性能,长期方案还是扩容或优化应用内存占用。