简述
简单说一下内存泄漏,总结就是该回收的没回收
java的JVM和android的DVM以及ART都是使用的可达性分析算法或者叫根搜索算法,就是说从根对象集合(GC Roots)开始搜索,能搜索到都属于不能清除的对象,其他的都可以定义为垃圾。
(1) Handler
引发原因
Handler发送的Message对象持有Handler的引用(可以去Message看源码-Handler target属性),如果我们在定义Handler的时候使用的是匿名方法的方式
Handler handler= new Handler(){public void handleMessage(Message msg) {}} ;
而且没有使用static修饰,内部方法会持有该类的引用(一般是Activity),只有这样你才能方便的调用Activity当中的View等属性。
但这时候activity被干掉了,Handler由于还被Message持有,无法被回收,而Handler又持有Activity的引用,导致整个链条都无法回收,Activity对象很大,占用内存空间大,而且还可能关联很多其他的引用(比如调用的接口请求),导致整个链条都无法回收,次数多了,达到内存上限就会OOM。
解决方法
(1)Handler定义为static的内部类(2)使用弱引用
private static class MyHandler extends Handler {
private WeakReference<Activity> weakAct;
public MyHandler(Activity act) {weakAct= new WeakReference<>(act);}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
if ( weakAct.get()!= null) {weakAct.get().textview.setText("");}
break; ... }}}
(2) context,静态View,单例模式
在一些需要传递context对象的方法中,尽量使用context.getApplicationContext();
静态对象生命周期长,比如单例模式,单例模式变量的生命周期是跟应用程序一样长的,如果在初始化的时候调用并持有了某个Activity的引用,那么这个Activity就无法被回收。静态的view也同理
(3) 变量声明尽量缩小作用域
比如某个变量只在某个方法中调用了,这个变量就不需要定义成全局变量(这时候android studio会给警告的),能private的就别用public。
未完待续.........