#memory泄露主要分为java和native 2种,本文主要介绍java#
测试每天从monkey中筛选出内存超标的app,提单流转到我
首先,辨别内存泄露类型(java,还是native)
- 从采到的dumpsys_meminfo_pid看java heap,native?heap大小分布,可判断出是java/native泄露
- 如果是java泄露,会抓到hprof文件(am dumpheap pid/pname?data/local/tmp/test.hprof)
其次,分析Hprof
- 明显的activity/fragment leak:销毁的activity/fragment对象的引用? ? ?
- 注意:有多个引用时要看全,每个引用链都可能导致泄露(这里是个大坑,掉下去很多次)(大概率是一个rootcause)
- 不明显的leak:
- 按ShallowSize从大到小顺序,筛选出Allocation数量/NativeSize最大的对象,通常是Bitmap,Service,ViewHolder,View,Dialog,Hashmap,Stub
- 一些特殊的对象本身就是GCRoot:Stub
- ServiceConnection,ViewHolder,Dialog都是要重点检查的对象
- 若Hprof的Native内存占用大,主要是Bitmap对象native内存占用大,再从Bitmap引用链可以反向推导出持有它的对象
- 若无法辨别出区别,可借助Mat,LeakSuspects分析出内存分布,找到疑似的泄露对象
- 选2份hprof文件,在mat上可对出对象的增长,若怀疑某个对象泄露了,再回到profiler中搜到对象和refrence
(Mat加载hprof要转换一下才生效,转化的方法是:
将.hprof文件拷贝到PC上的/ANDROID_SDK/tools目录下,并输入命令hprof-conv xxx.hprof yyy.hprof,其中xxx.hprof为原始文件,yyy.hprof为转换过后的文件)
据我的经验,有现场或找到复现路径基本100%可找到泄漏源,解决掉
最后,接下来分析下项目中常见的泄露Case: