Android内存泄漏及优化

1 内存泄漏的场景

1.1 单例持有了Activity的context的引用

    改为单例持有applicationContext对象的引用。

1.2内部非静态类持有了类的实例引用

    使用内部静态类。

1.3 Handler造成内存泄漏

    将Handler声明为静态的内部类 继承Handler

    通过弱引用的方式引入Activity

private HandlermHandler;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_login);

    mHandler =new MyHandler(this);

}

private static class MyHandlerextends Handler {

    private final WeakReferencemActivity;

    public MyHandler(Activity activity) {

        mActivity =new WeakReference(activity);

    }

    @Override

    public void handleMessage(Message msg) {

        if (mActivity.get() ==null) {

            LoginActivity instance = (LoginActivity)mActivity.get();

            int event = msg.arg1;

            int result = msg.arg2;

            Object data = msg.obj;

        }

    }

}

1.4线程造成内存泄漏

将自定义的AsncTask和Runnable类定义成静态的内部类

可以调用AsncTask.cancel()结束任务

private static class MyRunnable implements Runnable{ 

   @Override    public void run() {    }

}

1.5 WebView引起内存泄漏

加载的页面非常复杂,或包含很多图片,会占用很多的内存。

将WebView所处的类放在单独的进程中,必要的时候调用killProcess杀掉这个进程,以便占用的内存被回收。

    @Override

    protected void onDestroy() {

        destroyWebView();

        android.os.Process.killProcess(android.os.Process.myPid());

        super.onDestroy();

    }

    private void destroyWebView() {

        if (mWebView != null) {

            mWebView.pauseTimers();

            mWebView.removeAllViews();

            mWebView.destroy();

            mWebView = null;

        }

    }

2 内存优化框架

WeakReference、ReferenceQueue Dump出heap信息,分析出泄漏路径。

引用类型:

StrongReference

SoftReference(内存空间不够了,垃圾回收器才回收)

WeakReference(生命周期更短,垃圾回收器扫描到进行标记,下一次立即回收)

虚引用跟没有引用是一样的,垃圾回收器在任何情况下可以回收它

ReferenceQueue和 SoftReference、WeakReference联合使用

Leakcanary的使用

配置build.gradle:

 dependencies {

   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.2'

   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.2'

 }

public class LeakApplication extends Application {

private RefWatcher refWatcher;

@Override

public void onCreate() {

super.onCreate();

refWatcher= setupLeakCanary();

}

private RefWatcher setupLeakCanary() {

if (LeakCanary.isInAnalyzerProcess(this)) {

    return RefWatcher.DISABLED;

}

return LeakCanary.install(this);

}

public static RefWatcher getRefWatcher(Context context) {

LeakApplication leakApplication = (LeakApplication) context.getApplicationContext();

return leakApplication.refWatcher;

}

}


测试:

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

     setContentView(R.layout.activity_main);

    LeakThread leakThread = new LeakThread();

    leakThread.start();

}

class LeakThread extends Thread {

@Override

public void run() {

try {

    Thread.sleep(6 * 60 * 1000);

} catch (InterruptedException e) {

    e.printStackTrace();

}

}

}

@Override

protected void onDestroy() {

super.onDestroy();

RefWatcher refWatcher = LeakApplication.getRefWatcher(this);

refWatcher.watch(this);

}

}

你可能感兴趣的:(Android内存泄漏及优化)