CentOS 上排查 Swap 异常占用与疑似内存泄漏的实用流程
一 快速确认是否异常
- 观察整体内存与 Swap 趋势,确认是否存在持续增长或已接近耗尽的情况:
- 命令示例:
- free -h
- top/htop(按内存排序:top -o %MEM 或 htop --sort-key=PERCENT_MEM)
- vmstat 1 10(关注 si/so 是否持续不为 0)
- 查看内核日志,判断是否发生过 OOM Killer:
- grep -i “kill process” /var/log/messages
- dmesg | grep -i “out of memory”
- 读取内存细节,辅助判断是缓存导致还是匿名页(anon)导致:
- cat /proc/meminfo(关注 SwapTotal/SwapFree/SwapCached、MemAvailable)
- 经验判断:
- 若 available 充足但 Swap 占用高,常见于“历史活跃页被换出”或“长期运行进程累积占用”,并不必然代表泄漏;可结合后续步骤定位具体进程与原因。
二 定位占用 Swap 的进程
- 按进程汇总 Swap 使用(更准确反映“进程级”占用):
- 命令示例:
- sudo sh -c ‘for i in /proc/[0-9]; do pid=${i##/}; if [ “$pid” -gt 100 ]; then awk -v pid=“$pid” “/Swap:/{a+=$2} END {if (a>0) print pid, a/1024 "M"}” /proc/“$pid”/smaps 2>/dev/null; fi; done | sort -k2nr | head -n 10’
- 交叉验证与实时监控:
- watch -n 1 “ps aux | grep ”
- top/htop 中观察目标进程的 RSS/PSS 是否持续增长
- 说明:
- RSS 是常驻集大小,PSS 按比例计入共享页,更适合横向对比;若某进程的 PSS/RSS 随时间单调上升,且对应 Swap 占用同步上升,属于“高可疑泄漏”信号。
三 应用层深入诊断
- Java 应用:
- jmap -heap 查看堆内存分布与使用情况
- 结合监控/告警观察老年代(Old Gen)是否持续增长
- PHP-FPM:
- 检查 pm.max_children 等并发配置,避免 worker 进程无界增长
- 数据库(如 MySQL):
- mysqladmin ext | grep -i mem 查看内存相关指标
- 结合 innodb_buffer_pool_size 等配置评估是否合理
- 通用思路:
- 若观察到“进程级 PSS/RSS 持续增长 + 对应 Swap 占用同步增长”,优先怀疑应用层内存管理问题(对象生命周期、缓存未淘汰、连接/会话泄漏等)。
四 应急处理与缓解
- 临时扩容 Swap(为恢复业务争取时间):
- 示例:
- sudo fallocate -l 4G /swapfile
- sudo chmod 600 /swapfile
- sudo mkswap /swapfile
- sudo swapon /swapfile
- 永久生效需加入 /etc/fstab
- 限制失控进程(cgroups v1 示例):
- sudo cgcreate -g memory:/limited_service
- echo “1G” | sudo tee /sys/fs/cgroup/memory/limited_service/memory.limit_in_bytes
- sudo cgclassify -g memory:limited_service
- 清理页面缓存(谨慎,仅在低峰期执行,可能影响性能):
- sync
- echo 3 > /proc/sys/vm/drop_caches
- 回收 Swap(仅在“空闲物理内存充足”时执行,避免抖动):
- 降低内核换出倾向(治标不治本,用于缓解):
- 无法登录时的紧急处置(控制台/救援模式):
- 通过 iDRAC/iLO 进入单用户或救援环境,停止非关键服务、清理临时文件、必要时 kill 异常进程后再恢复服务。
五 根因修复与长期预防
- 修复方向:
- 代码审查与内存泄漏修复(确保动态分配必释放)
- 使用 智能指针(如 C++ 的 std::unique_ptr/std::shared_ptr)降低泄漏概率
- 完善 异常处理/资源释放 路径,避免异常分支未释放
- 应用层引入缓存淘汰策略与对象池,限制最大连接/会话数
- 监控与告警:
- 部署实时监控(如 netdata),并设置阈值告警(示例 Prometheus 规则):
- groups:
- name: memory.rules
rules:
- alert: HighMemoryUsage
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 90
for: 5m
labels:
severity: critical
annotations:
summary: “服务器内存使用率过高”
- 配置优化(按场景调整,非“一键万能”):
- 适度降低 vm.swappiness,必要时评估 zram/zswap 等更高效的 Swap 技术
- 数据库/中间件按负载与内存容量调参(如 InnoDB 缓冲池大小)
- 重要提醒:
- Swap 不是用来“修复”内存泄漏的,它只是缓解手段;根本解决仍需定位并修复应用或内核模块的内存问题。