Android内存泄漏场景

栏目: Android · 发布时间: 5年前

内容简介:如何判断,只用记住一点:A类实例引用B类实例,而A类实例的生命周期长于B类实例的生命周期。在Android开发中,内存泄漏的地方还是挺多的,有时候稍不注意就写出了一个内存泄漏的代码。所以说我们要熟记哪些地方容易发生内存泄漏,在代码Review的情况下很容易检查出来。单例模式使用的地方非常多,它的生命周期常常伴随着App的一生,所以说也十分容易造成内存泄漏。

如何判断,只用记住一点:A类实例引用B类实例,而A类实例的生命周期长于B类实例的生命周期。

泄漏场景

在Android开发中,内存泄漏的地方还是挺多的,有时候稍不注意就写出了一个内存泄漏的代码。所以说我们要熟记哪些地方容易发生内存泄漏,在代码Review的情况下很容易检查出来。

单例引起的内存泄漏

单例模式使用的地方非常多,它的生命周期常常伴随着App的一生,所以说也十分容易造成内存泄漏。

例如单例模式中引用Activity的Context,而单例模式的生命周期长于Activity。这里单例模式引用Activity的实例,当Activity被销毁,Activity无法被回收,造成内存泄露。

public class Single {
  private static Single instance;
  private Context context;
  private Single(Context context) {
    this.context = context;
  }
  public static Single getInstance(Context context) {
    if (instance == null) {
        instance = new Single(context);
    }
    return instance;
  }
}
复制代码

值得一提的是,如果这里引用的Application的Context,将无任何影响。因为Application的生命周期与单例模式同样长。

集合的内存泄漏

在静态集合里面添加对象,添加完成之后该集合将会一直引用此对象,该对象无法被释放。(不过我们也写不出这样沙雕的代码来!

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

解决方法:在使用完该集合之后,将集合清空。

匿名内部类以及非静态内部类

特点:匿名类和非静态内部类都持有外部类的引用

匿名内部类

Handler泄漏

匿名内部类引起的内存泄露,最典型的例子就是Handler泄漏。当Handler的消息没有发送完毕,Activity就被销毁了,此时Activity无法被即时回收。

public class MainActivity extends Activity{
    
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
           //do something...
        }
    };
    
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
复制代码

如何解决Handler泄漏呢?我们用static修饰Handler,这样Hanlder的生命周期就与Activity无关了。如果想引用Activity实例,这里可以用一个弱引用来获取。或者可以在Activity 的onDestroy() 方法中移除所有的消息 handler.removeCallbacksAndMessages(null);

public class MainActivity extends Activity{
    private final MyHandler handler = new MyHandler(this);
    
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
    
    private static class MyHandler extends Handler {
        private final WeakReference<MainActivity> mActivity;

        public MyHandler(MainActivity activity) {
            mActivity = new WeakReference<MainActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
          MainActivity activity = mActivity.get();
        }
  }
}
复制代码

Thread泄漏

在Activity中new Thread时,如果在子线程做耗时操作,当Activity被销毁后,子线程的工作并未完成,此时会内存泄漏。

public class MainActivity extends Activity{
    
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
复制代码

这里同样可以继承 Thread 实现静态内部类来解决。

static修饰的成员变量

如果成员变量被声明为 static,其生命周期将与整个app进程生命周期一样。

Stream未关闭

在调用了流之后,一定要记得关闭流。用到流的地方一般都是文件操作,虚拟机无法通过垃圾回收来释放这些资源。

其他泄漏

例如service忘记解除绑定,broadcastReceiver忘记解除订阅,EventBus忘记解除订阅等。

常用的检测内存泄漏的工具

光凭肉眼我们其实只能找出比较明显的内存泄露点,还有许多隐藏得比较深的内存泄露。那么我们如何找到这些点呢?当然是利用工具。

  • Android Lint:Android Studio提供的代码扫描分析工具
  • Leakcanary : Square 公司开源的「Android 和 Java 的内存泄漏检测库」

总结

在Android系统中,每个App最多能分配大约只有100-200MB的内存空间,因为内存不够,溢出而引起的程序崩溃还是不在少数。所以说,日常开发中还是要千万注意内存泄露。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Art and Science of Java

The Art and Science of Java

Eric Roberts / Addison-Wesley / 2007-3-1 / USD 121.60

In The Art and Science of Java, Stanford professor and well-known leader in CS Education Eric Roberts emphasizes the student-friendly exposition that led to the success of The Art and Science of C. By......一起来看看 《The Art and Science of Java》 这本书的介绍吧!

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具