内存泄漏定位清理脚本释放服务器占用内存资源
服务器可用内存越来越少、Swap 占用持续升高,不一定是业务高峰,更可能是某个进程存在内存泄漏。
本文用一套可落地的方法,带你借助 free、ps 等命令定位异常进程,再用清理脚本释放占用内存资源,全程零基础可照做。
先分清:内存泄漏和缓存占用
执行 free -m 查看内存时,很多新手一看 used 高就紧张,其实 Linux 会主动用空闲内存做缓存(buff/cache)。
判断是否泄漏,更可靠的指标是可用内存趋势和 Swap 使用量。
如果发现 available 持续下降、Swap 不断上涨,重启进程后内存恢复,再运行一段时间又涨回来,基本可以确认存在内存泄漏。
定位占用异常的可疑进程
登录服务器后,先执行下面两条命令:
free -m
ps aux --sort=-%mem | head -20
第一条看整体内存水位,第二条按内存占用从高到低列出前 20 个进程。
重点观察 %MEM 和 RSS 列,找出那些持续增长或远超正常水平的进程。
也可以用 top 动态观察:
top -o %MEM
如果某个 Java、Node、Python 或 PHP-FPM 进程的 RSS 数值只增不减,很可能就是泄漏源头。
用脚本安全清理并释放内存资源
清理脚本的核心思路不是盲目清理系统缓存,而是针对异常进程执行重启或上下限控制。
下面这个脚本适合常见 Web 服务场景:
#!/bin/bash
# 内存泄漏清理示例脚本,请根据实际进程名修改
PROCESS_NAME="php-fpm"
MEMORY_LIMIT=1024 # 内存阈值,单位 MB
PID=$(pgrep -f "$PROCESS_NAME" | head -1)
if [ -n "$PID" ]; then
RSS=$(ps -p "$PID" -o rss= | awk '{print $1}')
RSS_MB=$((RSS / 1024))
if [ "$RSS_MB" -gt "$MEMORY_LIMIT" ]; then
echo "$(date): $PROCESS_NAME 占用 ${RSS_MB}MB 超过阈值,重启中" >> /var/log/mem_clean.log
systemctl restart "$PROCESS_NAME"
fi
fi
将脚本保存为 /usr/local/bin/mem_clean.sh,赋予执行权限:
chmod +x /usr/local/bin/mem_clean.sh
建议先用 bash -x 跑一次,确认逻辑没问题,再加入 crontab 定时执行:
crontab -e
添加一行,每 10 分钟检查一次:
*/10 * * * * /usr/local/bin/mem_clean.sh
如果你的环境是宝塔面板,也可以在“计划任务”中新建 Shell 脚本任务,周期设为 N 分钟。
避坑:别乱杀进程,也别直接清缓存
很多教程会让你执行 sync && echo 3 > /proc/sys/vm/drop_caches,这个操作只清理页缓存,对真正内存泄漏没有帮助,反而可能短暂影响磁盘性能。
正确做法是定位并处理异常进程。
重启服务前,确认这是可重启的独立进程,不要对数据库主库或核心业务进程随意重启。
如果进程是系统服务,优先用 systemctl restart;
如果是用户态程序,建议先配合日志确认泄漏原因,再考虑升级代码或增加内存限制。
另外,OOM Killer 只能作为最后兜底,别把清理内存的希望全压在它身上。
验证内存是否真的释放了
脚本运行后,通过三个步骤确认效果:
- 再次执行
free -m,对比 available 和 Swap 数值。 - 查看
/var/log/mem_clean.log,确认触发记录和重启时间。 - 连续观察两三个周期,如果 Swap 不再持续增长,说明定位和清理有效。
free -m
cat /var/log/mem_clean.log
内存泄漏不会只发生一次,用好定时脚本只是应急手段。
长期来看,建议结合监控工具记录进程内存趋势,从代码或配置层面根治问题。
如果你正在处理内存泄漏定位清理脚本释放服务器占用内存资源相关任务,建议先把本文脚本跑通,再根据实际进程名和内存阈值做调整,遇到异常时优先回看避坑说明。