最近遇到一些事情,觉得挺憋屈的,可是再憋屈总得往前走吧!打工人,不好办啊!事情是这样的,笔者在芯片原厂负责SDK和行业解决方案输出的,可以理解成整体SDK turnkey方案。但是有些客户多少还要改一下自己的东西进去,所以问题来了。在我们释放SDK出来的时候也会有固件测试整体功能的,客户修改了自己的东西后,开发的程序跑起来十来分钟就oom了.我方leader跟客户对接呢又不那么自信似的,客户在群里反复抱怨程序有内存泄露. 我们在公司内也组织了再次内测,跑两天都没有任何内存泄露,因此我们建议客户在我们SDK的基础上,做增量的问题定位,把修改过的代码一点点加到原始SDK上去定位. 你猜现在客户都多牛逼,人家不干,拍着胸脯说我们改过的代码100%没有内存泄露,我们没有申请内存,客户反正就是不想去回退代码定位.
退一步,我们想客户把修改过的代码给我们,我们来定位,本身这客户也是我们的乙方,我们有付一定开发费给他们去给终端客户做一些少量的定制化开发,这些都是大佬们定的策略. 人家客户不给,说每个人写代码的习惯不一样,看代码也要很多时间.坦白地说也不无道理,但是没有代码我们又怎么去推进事情呢?我方领导放大招,要求我们拿客户固件来测测复现问题,再定位内存泄露。真的有点太别扭了,但又能怎么样呢,生活还得继续。
客户把有问题的固件发给我们,我们复测,确实很容易出问题,十来分钟就挂逼了. 我们监测了内存变化,确实十来分钟就把二十多M的可用内存干到只能4M之内,再慢慢减少,最后系统死掉。问题是复现了,怎么进一步定位呢?
/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/edsam49原创,转载请注明出处,谢谢!
/*****************************************************************************************************/
笔者想到了先用procrank来定位一下哪个进程是不是有内存泄露;procrank 命令可以获得当前系统中各进程的内存占用,从 /proc/pid/maps 中读取信息来进行统计,包PSS,USS,VSS,RSS。我们一般观察 Uss 来反映一个进程的内存使用情况,Uss 的大小代表了只属于本进程正在使用的内存大小,在此进程被杀掉之后,这些内存会被完整的回收。了解了这些细节后,我们就开始干吧!
好在客户应用起来之前,我们还有机会做一些其他操作,比如我们跑一个脚本来跑procrank监测内存,10秒钟我们执行一次,来观察。下图是开始之初阶段的,明显看出剩余内存还有近20M,cached 3604K;
跑到快死的时候情况如下:
从这两张图我们分析,app进程占用的uss并没有多大变化,因此可以判断应用程序是没有泄露的。那么问题来了,内存去哪了?
我们发现cached变成了21688K,明显增大了十几M,跟可用内存丢失的数据大小是基本吻合的。只是cached增加了,那就是文件系统之上的操作了,比如有新文件写到了内存哪里?那么系统也不小,同时段操作的文件也那么多,怎么进行下一步分析呢?
这个时候我就想到了用lsof来分析。lsof命令不仅可以查看进程打开的文件、目录,还可以查看进程监听的端口等socket相关的信息。那么还是跑起来看吧!
跑出来的东西文件不少,接近200个了;
李鬼就在里面了,要去排查甑别了。先排查我们SDK也有的,基本确认没有问题的,剩下的也少了。猛的一回头,可疑分子来了,
看见有一个pcm后缀的文件,因此从命令行去看这个路径下的这个文件,发现这个文件蹭蹭的往上在增加。真的实锤了!
证据都到这份上了,还能怎么说。客户拍着胸脯100%没问题的人在群里也低调了。
幸运的是这个问题找到了,不然得多怨啊!老板的理念,客户的问题也是我们的问题,多数时候这话也没错,不配合的情况下咋解决问题,需要点运气和智慧,这种环境下做成这样,你会不会也觉得憋屈?有做事稍微讲理一点的公司缺人否,不缺人的能否来给我们指导一下怎么讲理一点管理。