内存泄漏的核心表现是系统可用内存持续减少,即使没有高负载也会逐渐耗尽。通过以下命令快速确认:
free -h
:查看available
内存(系统可立即分配给应用的内存),若长期趋近0且swap
(交换分区)使用量持续增长,可能是内存泄漏的信号。top
/htop
:按%MEM
排序,观察是否有进程长期占据高内存且RES
(实际物理内存占用)持续上升,即使进程处于空闲状态也不下降。通过以下命令筛选出内存占用异常的进程:
ps aux --sort=-%mem | head -n 10
:列出内存占用前10的进程,重点关注**常驻内存(RES)**占比高且持续增长的进程(如Java、php-fpm、nginx等长期运行的服务)。top -o %MEM
:实时监控内存占用排名,观察进程内存变化趋势。对可疑进程进行深入分析,定位内存分配的具体模块:
pmap -x <PID>
:查看进程的内存映射表,按内存占用排序(sort -k3 -n | tail -n 20
),找出占用内存最多的模块(如动态库、堆内存等)。smem -r -k -p <PID>
:显示进程的真实物理内存使用(排除cache虚化),更准确反映进程的实际内存消耗。系统日志会记录内存异常事件,尤其是**OOM Killer(内存杀手)**的触发记录,可直接关联到泄漏进程:
dmesg | grep -i "memory\|oom"
:过滤内存相关日志,若出现Out of memory: Killed process <PID> (<process_name>)
,说明系统因内存不足杀死了该进程,此进程极可能是泄漏源。journalctl -k | grep -i "memory"
:查看内核日志,获取更详细的内存分配/释放错误信息(如kmemleak
检测到的内核泄漏)。若泄漏来自特定应用(如Java、PHP),需检查其自身日志中的内存错误:
OutOfMemoryError
(如java.lang.OutOfMemoryError: Java heap space
),通常伴随堆栈信息,指向内存泄漏的代码位置。Fatal error: Allowed memory size of X bytes exhausted
,说明脚本未释放内存,需检查脚本中的变量生命周期。对于疑似泄漏的进程,使用工具进行深度分析:
valgrind --leak-check=full ./your_program
运行,生成详细的内存泄漏报告(包括泄漏内存的大小、分配位置及类型,如definitely lost
表示明确泄漏)。-fsanitize=address -g
选项,运行程序时实时检测内存泄漏,输出更简洁的错误位置(比Valgrind更快)。echo 1 > /sys/kernel/debug/kmemleak
),然后查看cat /sys/kernel/debug/kmemleak
输出的泄漏内存块信息。若泄漏是“缓慢型”(如每天增长1%),需通过历史数据验证:
sar -r -f /var/log/sa/saXX
:查看指定日期的系统内存使用趋势(saXX
为日期文件,如sar -r -f /var/log/sa/sa10
查看10号的数据),确认内存是否持续增长而非临时峰值。通过以上步骤,可从“现象→进程→日志→代码”逐步缩小范围,最终定位内存泄漏的根源。排查过程中需结合多种工具和日志,避免遗漏内核、应用或第三方库的泄漏问题。