Android native内存泄露排查总结

Android开发通常涉及java层、native(c\c++)下的开发;

内存的泄露也可以分为dalvik和native两种;

java层的通常叫好分析,可以借助heapdump工具直接查看泄露的内存点;

重点关注native内存泄露问题,通常Android支持的工具都比较少而且难使用,依赖malloc_debug的也运行起来非常的慢,一些多媒体处理相关的软件根本没法调试;

下面是除工具以外,一些排查的经验方法:

1、反复运行可能出现泄露的程序步骤,尽量单一;

2、实现一个dump信息的脚本,1s执行一次,保存信息到文件,加上时间戳,包含以下内容

adb shell dumpsys meminfo com.xxx.demo // 内存信息,native,java,total

adb shell ps -t -p 11917                           // 进程下的所有运行线程id和name

adb shell ls -l /proc/11917/fd/                  // 进程下的所有打开的文件句柄

3、拿上以上信息后,可以基本确定以下几点:

根据运行同一程序步骤的不同时间dumpsys信息,对比里面内存数据大小,可以明确显示是native泄露还是java泄露;

根据运行同一程序步骤的不同时间线程数量对比,如果线程数量持续增大,而且同一个命名的线程重复多个,可以确认是该线程泄露引起,通常启动的线程没有结束,会导致泄露线程动态分配的栈空间;

根据运行同一程序步骤的不同时间fd数量对比,如果fd数量持续增大,而且同一个命名的fd重复多个,可以确认是该句柄未关闭,通常有文件、socket、steam等;

4、如果以上信息确认线程和句柄都没泄露,native泄露基本就是用户程序heap泄露,可以从一些几个方面排查:

使用的cjson获其他带有明确delete或destory或uninit的库没有调用释放;

使用裸指针,是否有new对象、数组、malloc等是否没释放,保持哪里申请的内存由哪里释放原则;

使用智能指针,是否有强指针循环引用导致不能释放;

使用stl标准库,里面存放指针时,是否清理容器的同时释放了指针指向内存;

5、2020.5.13补充一条经验,循环测试一种可以出现内存泄露的case

1)将每个执行周期的“关键点状态”打印出来,最好明确是正常流程下的状态还是异常流程下的状态;

2)测试保存2小时或者一个固定时间周期的log,同时按照上述dumpsys 的方式抓内存信息保存;

3)将内存分配的字节数筛选出来,粘贴到excel的一列中(可以使用excel的导入向导,支持将文本用空格分开为一列),选中一列插入绘制曲线图,得到一个内存趋势;

4)过滤保存日志的“关键点状态”,过滤出来后根据日志时间点,对照内存曲线排查,大致可以观察到内存增长可能和某个异常流程有关,或者某个特殊流程有关;

5)如果内存持续增长趋势,而且执行流程都是正常流程,那更简单些,跑一条单独的流程直接抓内存排查就好,可以注释局部程序模块验证排除;

你可能感兴趣的:(语言-c++,android,c++)