Android中的内存溢出和内存泄漏问题

Android中的内存溢出和内存泄漏问题

在Android中,我们会经常碰到一个异常OOM(Out Of Memory),这个叫内存溢出。有一天,一个朋友问我,内存泄漏问题怎么解决呀,我就巴拉巴拉一大堆OOM的解决方案丢了过去,然后只见朋友一脸懵逼的看着我,这两个东西是一回事吗?NO,这是两个概念,特意记录一下,避免以后再犯类似的错。

什么是内存溢出和内存泄漏

  1. 内存泄漏:

    内存泄漏(Memory leak),一般指应用申请的内存没有及时的释放,在第二次申请的时候又重新创建了对象,导致内存泄漏

    由此可知,如果在虚拟机的内存范围内,是不会造成程序崩溃的。但是次数多了,内存溢出就会导致内存泄漏。

  2. 内存溢出:

    内存溢出,就是我们开发中经常碰到的OOM异常,当向虚拟机申请内存的时候,没有更多的内存给你,这叫内存溢出。

    因此,我们可以大概总结出内存泄漏和内存溢出之间的关系:
    内存泄漏和内存溢出是两个不同的概念。内存泄漏可能导致内存溢出,内存溢出可能是内存泄漏引起的,也有可能是加载大图片等其他原因引起的,两者之间没有必然关系。

内存溢出和内存泄漏的引起原因及解决方案

  1. 常见的引起内存溢出的原因及解决方案:

    • 图片过大:
      方法一:通过等比缩放图片;

      //只保存图片大小,比保存图片到内存
      BitmapFactory.Options  options = new BitmapFactory.Options();
      options.inSampleSize = 2;
      Bitmap bmp =null;
      bmp = BitmapFactory.decodeResource(getResources(),R.id.iv_icon,options);
      //回收
      bmp.recycle(); 
      

      这种方式只是优化了内存溢出,改变图片的大小,并不能彻底解决内存溢出

      方法二:对图片采用软引用,及时进行recycle()操作

      SoftReference bitmap = new SoftReference(mBitmap);
      if(bitmap!=null){
          if (bitmap.get() != null && bitmap.get().isRecycled()){
              bitmap.get().recycle();
              bitmap = null ;
          }
      }
      

      方法三:使用框架加载图片
      使用UIL、Picasso、Glide、Fresco等图片框架来处理

    • 界面切换
      在横竖屏切换多次后很容易导致OOM。这种问题没有固定的解决方案,只能从几个方面分析。

      1. 看页面布局有没有大的图片,比如背景图之类的。
      2. 直接把XML配置成view再放到一个容器里面,避免重复加载。
      3. 在页面切换时尽可能少地重复使用一些代码。
    • 查询数据库没有关闭游标

      这种情况在开发当中经常碰见。当我们查询得到的结果集比较小的时候,对内存的消耗不容易被发现,只有在长时间大量操作的情况下才会出现内存问题,这样就会给以后的测试和问题排查带来困难和风险。

    • 构造Adapter时,没有使用convertView

      当convertView为空的时候,用setTag()为每一个View绑定一个存放控件的ViewHolder对象。当convertView不为空的时候,复用已经创建的view,使用getTag()方法绑定ViewHolder对象。

    • Bitmap对象不再使用时调用recycle()来释放对象。

      当一张图片不再使用时,可以调用Bitmap.recycle()方法回收此对象的像素所占用的内存空间,但是这也不是必须的,视情况而定。

    • 其他

      需要释放的资源一定要在用完之后记得释放对应的资源。

  2. 常见的引起内存泄漏的原因及解决方案:

    • 单例模式持有外部本应该被释放的对象
    • Android特殊组件或者类忘记释放
    • 网络请求或者其他异步线程。
      解决内存泄漏的问题的方法就是多使用软引用和弱引用,当对象不需要的时候只要系统执行gc操作就会将这些内存回收,同时将需要释放的资源或类记得及时释放。

参考文章:内存泄漏弄个明白

你可能感兴趣的:(andriod学习)