下面介绍三种检测内存泄漏的方法
1.用adb shell dumpsys meminfo packagement
打开app之后,进入相应进程,输入adb shell dumpsys meminfo packagement(进程名) 即可查看
需要关注的就是Views和Activities的对应数量 ,这个代表你当时输入这条命令行,你的应用中的View数量和Activity的数量;
在正常情况下:(views和Activity的数量都应该是0)
但是如果当你立刻关闭应用时输入命令行:
如果activity数量不为0,即代表有内存泄漏;
activity的数量可能在10s后重新输入命令行又为零,是因为可能存在mhandler这种延时性的内存泄漏,如果一直都不为零,那就是比较严重的内存泄漏问题。
2.用memory profile;
这时Android studio自带的内存分析器;
GC按钮主要是在dump java heap前进行回收,然后再点击dump java heap;
在怀疑部分结束后点击dump java heap之后,就会自动生成hprof文件;同时能在Androidstudio中看到内存泄漏的情况;
案例分析:
如上可以看到内存抖动;
内存抖动原因:1.循环体内new对象 2.ondraw 创建对象
3.可以用MAT分析Androidstudio生成的hprof文件
如果HPROF文件是通过AndroidStudio的profile工具导出的,由于这个不是 mat 工具用到的标准文件,我们需要使用 sdk 自带的platform-tools/hprof-conv.exe
工具进行转换,命令为:
hprof-conv -z 1.hprof 1_mat.hprof
用mat能看到比Androidstudio生成的分析更加详细的结果;
内存泄漏举例
有哪些情况会发生内存泄漏:
1.单例造成
2.Handler造成
3.线程造成(2 3都是静态内部类持有外部activity)
4.资源对象没有关闭
解决方法:将传入的Context改为ApplicationContext ,这样两个对象的生命周期一样长;
在Java中,非静态内部类和匿名内部类都会默认持有所属的外部类的引用,而静态内部类不会持有;
所以解决方法1还可以先只改为静态内部类,不采用弱引用;
解决方法1:(改为静态内部类,并弱引用)
使用静态内部类中并以弱引用的方式声明外部类,从而使得短生命周期对象会被回收!!!
解决方法2:Activity退出消息队列时,清除消息队列中的未处理的消息;
线程造成的内存泄漏:
和Handle类似,也是创建Runnable非静态匿名内部类时,会默认持有外部Activity引用,当Activity销毁之前,
消息还没完成,于是长生命周期持有短生命周期;
解决方法:使用静态内部类并以弱引用的方式来申明外部类的引用,以及任务的销毁;
第四种属于资源型对象,不关闭会导致内存泄漏;