Linux内存泄漏定位关键是区分“假涨”与“真漏”:available持续下降、Slab单向攀升、进程RSS线性增长才是真实泄漏信号;需结合free、vmstat、ps、pmap、slabtop及trace-cmd分层排查用户态与内核态源头。

Linux内存泄漏定位,核心是区分“假涨”和“真漏”。系统自动缓存(buff/cache)上涨属于正常行为,真正危险的是available持续下降、Slab长期单向攀升、进程RSS线性增长——这些才是泄漏信号。
盯住free输出的关键三列
执行watch -n 5 'free -h'观察趋势:
- available:不是free列,而是内核估算的“此刻可立即分配”的内存。从4G掉到300M且不回升,就是强泄漏提示;
- buff/cache:短期上涨合理,若随时间单向增长、且available不同步恢复,说明有内存被“钉住”无法回收;
- 不要看used:used = total − free − buff/cache,而buff/cache中大部分可随时释放,used涨≠泄漏。
用vmstat确认系统是否在“挣扎”
运行vmstat 1,关注以下指标是否异常:
- sr 或 re > 0 并持续存在:kswapd内核线程正疯狂扫描LRU链表,内存压力已实质化;
- si/so 非零且跳动:开始swap换页,物理内存严重不足;
- in(中断)和 cs(上下文切换)明显升高 + available同步下降:可能指向高频内核分配路径,比如网络收包、定时器反复申请内存。
分层定位泄漏源头
先快速判断是用户态还是内核态问题:
- 用户进程侧:用ps aux --sort=-%mem | head -10找RSS最高进程;再结合生命周期判断——是否本该退出却常驻?连接数/请求数是否线性增长?用pmap -x <pid>查看堆、mmap区是否持续扩张;
- 内核侧重点看Slab:执行cat /proc/meminfo | grep -E "Slab|SReclaimable|SUnreclaim"。若Slab持续上涨、SReclaimable不涨(即不可回收部分占比高),大概率是驱动或模块中kmalloc后未kfree;进一步用slabtop找增长最快的slab cache(如dentry、size-4096),再查/proc/slabinfo确认对象数量变化;
- 确认是内核泄漏后:可用trace-cmd record -e kmem:kmalloc -e kmem:kfree -T跟踪特定大小分配/释放,比对ptr地址是否成对出现。
优先排查常见诱因
很多“内存上涨”其实有明确归因,建议按顺序快速验证:
- curl HTTPS探测脚本:旧版curl(如7.19.7)+ NSS库存在dentry泄漏,停掉脚本或升级即可缓解;
- /proc/schedstat读取:某些内核版本中反复读该文件会泄漏size-4096内存,上游已有补丁(commit 8e0bcc722289);
- BPF或eBPF map:未设置max_entries或未及时清理过期条目,导致内核内存持续累积;
- 大量短命子进程(如lftp、sleeping进程堆积):atop -m可查RSIZE,结合启动时间过滤清理,避免一次性kill引发高负载。










