Android 进阶解密-热修复

在这里插入图片描述

内存泄漏

什么是内存泄漏

内存泄漏(Memory Leak):是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

比如:当Activity的onDestroy()方法被调用后,Activity以及它涉及到的View和相关的Bitmap都应该被回收掉。但是,如果有一个后台线程做耗时操作,导致生命周期比Activity长,造成GC无法回收Activity,就造成内存泄漏。

内存泄漏后果

它是造成应用程序OOM的主要原因之一。由于android系统为每个应用程序分配的内存有限,当一个应用中产生的内存泄漏比较多时,就难免会导致应用所需要的内存超过这个系统分配的内存限额,这就会导致程序崩溃等严重后果。

检测工具

最常见的是:Leakcanary leakCanarySquare开源框架,是一个Android和Java的内存泄露检测库,如果检测到某个 activity 有内存泄露,LeakCanary 就是自动地显示一个通知,所以可以把它理解为傻瓜式的内存泄露检测工具。通过它可以大幅度减少开发中遇到的oom问题,大大提高APP的质量。

常见的内存泄漏

单例造成的内存泄漏

单例在Android中经常使用,如果使用不当会造成内存泄漏,因为单例的静态特性使得他的生命周期与应用的生命周期一样长,这就造成当前对象的生命周期比单例短,单例又持有该对象的引用,GC无法回收该对象,就这导致内存泄漏,比如Context使用不当: 这里的Context如果使用的是activity的Context,造成单例持有activity的引用,它的生命周期又是整个应用的生命周期,导致activity无法销毁。则有可能造成内存泄漏,比如:

public class LoginManager {
   
    private static LoginManager mInstance;
    private Context mContext;
 
    //问题代码
    private LoginManager(Context context) {
   
        this.mContext = context;          
        //修改代码:this.mContext = context.getApplicationContext();
    }
    public static LoginManager getInstance(Context context) {
   
        if (mInstance == null) {
   
            synchronized (LoginManager.class) {
   
                if (mInstance == null) {
   
                    mInstance = new LoginManager(context);
                }
            }
        }
        return mInstance;
    }
    public void get() {
   }
}

场景: 在一个Activity中调用的,然后关闭该Activity则会出现内存泄漏。 LoginManager.getInstance(this).get();

解决方案: 可以将Context修改为AppLication的Context,代码如下: **this.mContext = context.getApplicationContext();** 此时传入的是 ApplicationContext,因为 Application 的生命周期就是整个应用的生命周期,此时Context就和整个应用的生命周期一样,与单例的生命周期一样,单例持有的是整个application的引用,与activity无关,此时activity就正常可以销毁了,所以这将没有任何问题。

非静态内部类造成的内存泄漏

比如:

public class TestLeak extends AppCompatActivity {
   
    private static InnerClass mInnerClass = null;    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_test);
        if (mInnerClass == null) {
   
            mInnerClass = new InnerClass();
        }
    }    
    class InnerClass {
   
    }
}

代码中有一个非静态内部类InnerClass,有一个静态变量mInnerClass,在onCreate中进行了初始化操作,这个内部类实例就持有activity的强引用,而静态变量的生命周期与应用的生命周期一样长,而activity的生命周期比它短,想要销毁时,被持有引用,无法回收,继而造成内存泄漏。 解决方案:

  1. 将内部类设置为静态内部类,静态内部类不会持有外部类的引用,比如: public class TestLeak extends AppCompatActivity { private static InnerClass mInnerClass = null; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_test); if (mInnerClass == null) { mInnerClass = new InnerClass(); } } static class InnerClass { } }
  2. 将该内部类抽取出来封装成一个单例,使用Application的Context。 public class InnerClass { private volatile static InnerClass instance; private InnerClass(Context context) { } public static InnerClass getInstance(Context context) { if (instance == null) { synchronized (InnerClass.class) { if (instance
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值