Android内存泄漏笔记

实操 MAT:
androidProfile进行headdump

命令行导出快照

然后MAT进行配对

原理:
GC回收机制,某对象不再持有任何的引用的时候才会回收
问:如果某对象被别的对象引用了,就不能被GC回收
否,软引用、虚引用、弱引用——》用来避免内存过度消耗以及容易内存泄漏的
该对象一直往上追溯引用,能追溯到GC Root 引用点才能说不被GC回收

可以作为GC Root 引用点的:(产生内存泄漏)
JAVAStack中引用的对象
方法区中的静态引用指向对象
方法区常量引用指向的对象
Native方法中JNI引用的对象
Tread--活着的对象

例子
1.单例导致内存泄漏
单例模式中的静态方法使用 Context,会导致静态单例会继续持有Activity引用,导致无法释放

   //修改
   context = context.getApplicationContext();

2.静态变量导致内存泄露
生命周期不一致导致内存泄漏
优化修改:
进行少的使用,或者在适当的位置重置为null

3.非静态内部类导致内存泄露
Handler、Thread、AsyncTask
msg持有Handler,mHandler 会作为成员变量保存在发送的消息 msg 中,msg就间接持有Activity,导致Activity推出后,Looper还是在轮询,导致无法释放Activity,进而引起内存泄漏。
最后别忘了mHandler.removeCallbacksAndMessages。
优化修改:

private static class MyHandler extends Handler {
private WeakReference activityWeakReference;
public MyHandler(MainActivity activity) { 
activityWeakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = activityWeakReference.get(); 
if (activity != null) {
if (msg.what == 1) { // 做相应逻辑
    } }
   }}
}

4.未取消注册或回调导致内存泄露
例如广播和Retrofit+RxJava
5.Timer 和 TimerTask 导致内存泄露
cancel 掉 Timer 和 TimerTask
6.集合中的对象未清理造成内存泄露
7.资源未关闭或释放导致内存泄露
8.属性动画造成内存泄露
9.WebView 造成内存泄露

总结:
构造单例的时候尽量别用 Activity 的引用;
静态引用时注意应用对象的置空或者少用静态引用;
使用静态内部类+软引用代替非静态内部类;
及时取消广播或者观察者注册;
耗时任务、属性动画在 Activity 销毁时记得 cancel;
文件流、Cursor 等资源及时关闭;
Activity 销毁时 WebView 的移除和销毁。

参考:
网易
MAT 下载地址

你可能感兴趣的:(Android内存泄漏笔记)