温馨提示×

CentOS Swap内存泄漏怎么排查

小樊
37
2025-12-31 02:21:25
栏目: 智能运维

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(仅在“空闲物理内存充足”时执行,避免抖动):
    • swapoff -a && swapon -a
  • 降低内核换出倾向(治标不治本,用于缓解):
    • sysctl vm.swappiness=10
  • 无法登录时的紧急处置(控制台/救援模式):
    • 通过 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 不是用来“修复”内存泄漏的,它只是缓解手段;根本解决仍需定位并修复应用或内核模块的内存问题。

0