常见泄漏类型概览

本章从现象识别→数据采集→原因定位→修复动作→复测→预防六个阶段,横向对比五种工作流中频繁出现的泄漏类型。重点建立泄漏排查的通用判断规则,为后续章节的专项案例打下基础。

五类泄漏识别与排查树 工作泄漏现象 内存泄漏 OOM / 堆增长 句柄泄漏 fd / socket 用尽 连接池泄漏 连接不归还 缓存脏数据 过期 / 不一致 日志文件堆积 磁盘写满 / inode 满 诊断 heap profile VJ 内存快照 诊断 lsof / proc fd 句柄泄漏工具 诊断 池使用率监控 连接老化日志 诊断 TTL / 过期分析 数据一致性校验 诊断 日志轮替配置 磁盘使用率曲线 判断规则:先选泄漏类型→再按诊断方法采集数据→锁定根因
核心判断规则:遇到周期性 Work 未清理时,先按五类泄漏的典型现象对号入座,再执行对应诊断工具,避免盲目猜测。

现象识别

泄漏类型 典型现象(故障症状) 怀疑方向
内存泄漏 进程 RSS 持续增长 → OOM kill;响应变慢;GC 频繁 未释放的堆对象、全局容器膨胀
句柄泄漏 “Too many open files”错误;socket 连接拒绝;进程 fd 数接近 ulimit 未关闭的文件/ socket / 定时器
连接池泄漏 数据库/微服务调用超时;连接池监控显示 active 连接数持续攀升 连接获取未归还、忘记 close
缓存脏数据 业务返回过期或错误数据;缓存命中率异常;数据一致性告警 TTL 未设置、更新未清除缓存、竞争条件
日志文件堆积 磁盘使用率告警;inode 耗尽;日志目录文件数量巨大 logrotate 未配置、轮替策略失效、循环日志未清理

数据采集

每类泄漏的采集工具与指标如下表所示,建议建立巡检脚本定期采集。

泄漏类型 采集命令/工具 关键指标
内存泄漏 top -p PID / pmap -x / jemalloc heap profile RSS 增长率、堆块数量、泄漏对象大小
句柄泄漏 lsof -p PID / ls -la /proc/PID/fd fd 总数、未关闭 socket 数量、类型分布
连接池泄漏 应用连接池监控接口 / netstat -anp | grep TIME_WAIT active 连接数、idle 连接数、连接创建速率
缓存脏数据 缓存系统(Redis/Memcached)info 命令 / 业务对比脚本 过期 key 数量、缓存 miss 率、源数据差异
日志堆积 du -sh /var/log/* / df -i / logrotate -d 磁盘使用率、inode 使用率、日志文件个数

原因定位

基于采集的数据,通过故障树(Fault Tree)方法逐层缩小根因。常见根因归类:

  • 内存泄漏:全局静态容器(List/Map)只增不减;回调注册未反注册;JNI/FFI 未释放资源。
  • 句柄泄漏:网络请求异常未关闭连接;文件流未在 finally 或 defer 中关闭;定时器创建未取消。
  • 连接池泄漏:客户端未调用 close() 或 returnConnection();连接池超时回收配置过小;业务长事务占用连接。
  • 缓存脏数据:更新数据后未删除/刷新缓存;多副本间缓存过期时间不一致;竞争条件导致旧缓存先被写入。
  • 日志堆积:日志级别误设为 DEBUG;logrotate 未生效(权限/路径错误);异步日志队列积压。
注意:在定位阶段,一定要区分真实泄漏和正常增长。例如:连接池在高峰期 active 增加是合理的,低谷未回落才是泄漏线索。

修复动作

泄漏类型 典型修复方法
内存泄漏 增加弱引用 / 手动置 null / 限制容器大小 / 使用分析工具修复
句柄泄漏 确保 finally / using / defer 中关闭资源;增加句柄统计面板
连接池泄漏 完善连接归还逻辑;增加连接泄漏检测(monitor); 缩短空闲超时
缓存脏数据 统一缓存更新策略(Cache-Aside / Write-Through);缩短 TTL
日志堆积 配置 logrotate 并测试轮替;按业务设置日志保留天数;启用限流

复测

修复后必须执行压力复测,验证泄漏不在重现。复测指标:

  • 内存泄漏:运行 24h 后 RSS 保持在基线 ±5%,无 OOM。
  • 句柄泄漏:fd 数稳定在 (base + 正常工作数量) 范围内。
  • 连接池泄漏:active 连接数在压力停止后回落到空闲水平。
  • 缓存脏数据:缓存与源数据一致性校验通过,miss 率下降。
  • 日志堆积:磁盘使用率不再持续上升,logrotate 测试正常。
复测技巧:在测试环境模拟 120% 的峰值流量,同时注入网络抖动、数据库延迟等异常,看泄漏是否复现。

预防

从流程与工具层面建立防护网:

  1. 监控指标:将 RSS、fd 数、连接池利用率、磁盘使用率加入告警,设置上下限。
  2. 代码审查模板:将资源释放、连接归还、缓存刷新作为 Review 必检项。
  3. 自动化回归:每次发布前执行泄漏检测脚本(如 valgrind / heap profiler)。
  4. 定期演练:每月一次“泄漏攻防战”,用混沌工程注入泄漏场景验证告警与恢复能力。
  5. 知识沉淀:将常见泄漏根因整理成排查手册,纳入新人培训。