内存泄漏的处理

2020-10-27  本文已影响0人  18b434fc17bb

单例模式

public void SingleInstanceTest {
    private static SingleInstanceTest mInstance;
    private Context mContext;

    private SingleInstanceTest(Context context){
        this.mContext = context.getApplicationContext();
    }

    public static SingleInstanceTest newInstance(Context context){
        if(mInstance == null){
            mInstance = new SingleInstanceTest(context);
        }
        return mInstance;
    }
}

用到Activity或Context的实体类

使用弱引用(WeakReference)改进

public class Test{

    private WeakReference<Context> mWeakReference;

    public Test(Context context){
        this.mWeakReference = new WeakReference<>(context);
    }

    public Context getContext(){
        if(mWeakReference.get() != null){
            return mWeakReference.get();
        }
        return null;
    }
}

外部调用时

Test test = new Test(MainActivity.this);

非静态内部类/匿名类(耗时线程)

静态内部类和非静态内部类的对比

class对比 静态内部类 非静态内部类
与外部class引用关系 如果没有传入参数就没有引用 自动获得强引用
被调用时需要外部实例 不需要 需要
能否调用外部class中的变量 不能
生命周期 自主的生命周期 依赖于外部类,甚至比外部类更长

解决

@Override
protected void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacksAndMessages(null);
}
# 静态集合
>例如

static List<Object> objectList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Object obj = new Object();
objectList.add(obj);
obj = null;
}

例子中,循环多次将new出来的对象放入静态集合中,因为静态变量的生命周期和应用程序一致,而且他们所引用的对象Object也不能释放,造成了内存泄漏。
>解决:在静态集合使用后,删除元素,再将静态集合置空。如:

objectList.clear();
objectList = null;

其他情况

1.需要手动关闭的对象没有关闭
- 网络、文件流忘记关闭
- 手动注册广播,退出时忘记unregisterReceiver()
- Service执行完成后忘记stopSelf()
- EventBus等观察者模式的框架忘记手动解除注册
2.static关键字修饰的成员变量
3.ListView 的 Item 泄漏

排查内存泄漏的工具

1.Android Lint(Android studio提供的代码扫描分析工具
2.leakcanary


本篇文章参照:Android 关于内存泄露,你必须了解的东西

上一篇 下一篇

猜你喜欢

热点阅读