服务器内存泄漏怎么排查?Linux进程内存分析与处理实操

服务器内存泄漏怎么排查?Linux进程内存分析与处理实操

内存泄漏 vs 内存占用高:先判断是哪种问题

很多人看到 free -h 显示内存使用率很高就认为是内存泄漏,其实不一定。Linux 会把空闲内存用作文件缓存(buff/cache),这是正常行为,不是泄漏。真正的内存泄漏特征是:某个进程的内存占用随时间持续单调增长,重启后恢复,运行一段时间后再次增长。


一、判断是否真的存在内存泄漏

# 正确理解内存使用情况
free -h

# 输出示例:
#               total   used    free    shared  buff/cache  available
# Mem:          3.8Gi   1.2Gi   200Mi   50Mi    2.4Gi       2.3Gi
#
# "available" 才是实际可用内存,不是 "free"
# buff/cache 是系统缓存,需要时会自动释放

# 查看 available 内存是否随时间持续下降(每 5 分钟记录一次)
watch -n 300 'free -m | grep Mem >> /tmp/mem_log.txt'

如果 available 内存持续单调下降,且重启某个进程后恢复,基本可以确认是该进程存在内存泄漏。


二、定位内存占用最高的进程

# 按内存使用率排序,显示前15个进程
ps aux --sort=-%mem | head -16

# 更直观的方式:htop(按 F6 选择按 MEM% 排序)
htop

# 查看某个进程的详细内存使用
# 替换 PID 为实际进程号
cat /proc/PID/status | grep -E "VmRSS|VmSize|VmPeak"

三、跟踪进程内存随时间的变化

# 每30秒记录一次指定进程的内存使用
PID=12345  # 替换为实际 PID
while true; do
    echo "$(date): $(ps -o pid,rss,vsz,comm -p $PID | tail -1)" >> /tmp/mem_track.log
    sleep 30
done &

# 查看记录
cat /tmp/mem_track.log

如果 RSS(实际物理内存)持续增长且不释放,确认存在内存泄漏。


四、用 pmap 分析进程内存映射

# 查看进程的内存映射详情
sudo pmap -x PID | sort -k3 -rn | head -20

# 输出各内存段的地址、大小、实际驻留大小
# 关注 heap 段是否异常大

五、常见应用的内存泄漏场景与解决

PHP / PHP-FPM 内存泄漏

PHP 是进程模型,通常不存在长期运行的内存泄漏,但某些插件或代码会导致单次请求内存占用异常高,积累后导致 OOM。

# 查看 PHP-FPM 进程内存
ps aux | grep php-fpm | awk '{print $6/1024 " MB\t" $11}' | sort -rn | head -10

# 限制每个 PHP-FPM 进程的内存上限
sudo nano /etc/php/8.1/fpm/php.ini
# memory_limit = 256M  (单个请求最大内存)

# 配置 PHP-FPM 进程在处理一定请求数后自动重启,防止内存积累
sudo nano /etc/php/8.1/fpm/pool.d/www.conf
# pm.max_requests = 500

Node.js 内存泄漏

Node.js 最常见的内存泄漏原因:全局变量累积、事件监听器未移除、闭包持有大对象引用、缓存无上限增长。

# 启用 Node.js 内存快照(需应用代码支持)
node --inspect app.js

# 或使用 --max-old-space-size 限制最大内存,超出后报错而非无限增长
node --max-old-space-size=512 app.js

生产环境最实用的临时方案:配置 PM2 在内存超过阈值时自动重启:

pm2 start app.js --max-memory-restart 400M

Python 内存泄漏

# 使用 memory_profiler 分析内存使用
pip install memory-profiler

# 在代码中添加装饰器
from memory_profiler import profile

@profile
def my_function():
    # 你的代码
    pass

六、临时缓解:释放 Linux 页面缓存

# 释放页面缓存(不影响运行中的进程,安全操作)
sudo sync && sudo echo 3 > /proc/sys/vm/drop_caches

# 注意:这只能释放系统缓存,无法释放进程本身的内存泄漏

总结

内存泄漏排查步骤:free -h 观察 available 趋势 → 用 ps aux 找出增长最快的进程 → 用脚本跟踪该进程 RSS 变化 → 根据进程类型(PHP/Node/Python)进入对应排查路径 → 短期用重启或内存限制缓解,长期修复代码根因

内存频繁不足影响业务稳定,IDC.Net 香港独立服务器提供独占物理内存,不受其他用户影响,月付 299 元起,支持按需升级内存配置,支付宝 / USDT 付款。

Telegram