Linux 内存泄漏排查指南

问题现象

服务器运行一段时间后,可用内存持续下降,最终导致 OOM Killer 触发或服务崩溃。

排查步骤

1. 确认内存使用情况

1
2
3
4
5
6
7
8
# 查看整体内存使用
free -h

# 查看各进程内存占用
ps aux --sort=-%mem | head -20

# 查看内存详细分布
cat /proc/meminfo

2. 定位可疑进程

1
2
3
4
5
# 持续监控进程内存变化
watch -n 5 'ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -20'

# 查看进程详细内存信息
cat /proc/<PID>/status | grep -E "VmSize|VmRSS|VmData"

3. 分析内存泄漏类型

  • 用户态泄漏:应用程序分配后未释放
  • 内核态泄漏:内核模块或驱动问题
  • 缓存堆积:Page Cache 未及时回收
1
2
3
4
5
# 查看 slab 缓存
slabtop -o

# 查看内核内存
cat /proc/slabinfo | head -30

4. 使用工具深入分析

1
2
3
4
5
6
7
8
# 使用 valgrind 检测 C/C++ 程序
valgrind --leak-check=full ./your_program

# 使用 pprof 分析 Go 程序
go tool pprof http://localhost:6060/debug/pprof/heap

# 使用 jmap 分析 Java 堆
jmap -heap <pid>

解决方案

临时缓解

1
2
3
4
5
# 清理 Page Cache
sync && echo 3 > /proc/sys/vm/drop_caches

# 重启泄漏进程
systemctl restart <service>

根本解决

  1. 修复代码中的内存分配逻辑
  2. 设置合理的内存限制(cgroups)
  3. 配置 OOM Score 调整优先级
  4. 添加内存监控告警

预防措施

  • 定期更新内核和驱动程序
  • 设置内存使用告警阈值(80%)
  • 使用 systemd 配置 MemoryLimit
  • 定期重启非关键服务

相关命令速查

命令 用途
free -h 查看内存概况
top -o %MEM 按内存排序进程
smem -tk 查看共享内存
pmap -x <pid> 查看进程内存映射