接下来的排查思路是:
1.监控系统中每个用户进程消耗的PSS (使用pmap工具(pmap pid)).
PSS:按比例报告的物理内存,比如进程A占用20M物理内存,进程B和进程A共享5M物理内存,那么进程A的PSS就是(20 – 5) + 5/2 = 17.5M
2.监控/proc/meminfo输出,重点观察Slab使用量和slab对应的/proc/slabinfo信息
3.参考/proc/meminfo输出,计算系统中未被统计的内存变化,比如内核驱动代码
直接调用alloc_page()从buddy中拿走的内存不会被单独统计
以上排查思路分别对应下图中的1,2,3 :
通过监控/proc/slabinfo也发现SReclaimable 的使用量不停增长
- while true;
- do
- sleep 1 ;
- cat /proc/slabinfo >> /tmp/slabinfo.txt ;
- echo "===" >> /tmp/slabinfo.txt ;
- done
由此判断很可能是内核空间在使用size-4096 时发生了内存泄漏.
接下来使用trace event(tracepoint)功能来监控size-4096的使用和释放过程,
主要用来跟踪kmalloc()和kfree()函数对应的trace event, 因为他们的trace event被触发之后会打印kmalloc()和kfree()所申请和释放的内存地址,然后进一步只过滤申请4096字节的情况。
- #trace-cmd record -e kmalloc
- -f 'bytes_alloc==4096' -e kfree -T
(-T 打印堆栈)
等待几分钟之后…
- #cp /sys/kernel/debug/tracing/trace_pipe /tmp/kmalloc-trace
#trace-cmd report
以上步骤相当于: