当前位置: 首页 > 科技观察

一次性解决Linux内核内存泄漏全过程

时间:2023-03-13 12:04:14 科技观察

什么是内存泄漏:程序向系统申请内存,不再需要后,不释放内存,归还给系统用于回收,导致请求的内存被浪费。发现系统内存使用量随着时间的推移,消耗的内存越来越多,如下图:接下来的排查思路是:1.监控系统中每个用户进程消耗的PSS(使用pmaptool(pmappid)).PSS:按比例上报的物理内存,例如进程A占用20M物理内存,进程B和进程A共享5M物理内存,则进程A的PSS为(20-5)+5/2=17.5平方米。监控/proc/meminfo输出,重点观察Slab的使用情况和slab对应的/proc/slabinfo信息3.参考/proc/meminfo输出,计算系统未统计的内存变化,如内核驱动代码直接调用alloc_page()从buddy那里拿走的内存不会单独统计。以上排查思路分别对应下图中的1、2、3:在排查过程中,发现系统非常空闲,没有运行任何用户业务进程。其中,在使用slabtop监控slab的使用情况时,发现size-4096一直在增长。通过监控/proc/slabinfo,也发现SReclaimable的使用量不断增长whiletrue;dosleep1;cat/proc/slabinfo>>/tmp/slabinfo.txt;echo"===">>/tmp/slabinfo.txt;done由此判断,很有可能是内核空间在使用size-4096时发生了内存泄漏。接下来使用跟踪事件(tracepoint)函数来监听size-4096的使用和释放过程主要是用来跟踪kmalloc()和kfree()函数对应的trace事件,因为它们的trace事件被触发后,kmalloc()和kfree()请求和释放的内存地址会被打印出来,然后进一步只过滤请求4096字节的情况。#trace-cmdrecord-ekmalloc-f'bytes_alloc==4096'-ekfree-T(-Tprintstack)等待几分钟后...#cp/sys/kernel/debug/tracing/trace_pipe/tmp/kmalloc-trace#trace-cmd报告的上述步骤相当于:等待几分钟后...kmalloc对应的ptr值没有kfree对应的ptr值说明cat进程在内核空间使用size-4096后没有释放,造成内存泄漏。为了进一步准确定位是使用哪个内核函数引起的问题,手动触发vmcore#echoc>/proc/sysrq-trigger,然后使用crash工具分析vmcore:#crash./vmcore./vmlinux.debug阅读上面kmalloc应用ptr内存信息(从0xffff880423744000内存开始读取4096字节,并以字符形式显示)发现从上面几个ptr内存读取的内容非常相似。如果你仔细看,你会发现它们都是从/proc/schedstat输出的内容。看了相关代码,发现看了/proc/schedstat的内容后,内存确实没有释放,后来发现上游内核有patch解决这个问题:commit:8e0bcc722289fixaleakin/proc/schedstats本文转载自微信公众号》《Linux代码阅读领域》,可通过以下二维码关注。转载本文请联系Linux代码阅读领域公众号。