内存溢出和解决方法

  Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的设备为24M。因此,我们所能利用的内存空间是有限的,如果我们的内存占用超过了一定的水平,就会出现OutOfMemory的错误。

内存溢出的几种情况

资源释放问题

  因为程序代码的问题,长期保持某些资源,如Context、Cursor、IO流的引用等,资源得不到释放造成内存泄漏。

对象内存过大问题

  保存多个耗用内存过大的对象,如Bitmap、XML文件等,造成内存超出限制。

static关键字的使用问题

  当使用static来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例,比如Context,就需要谨慎使用。

  针对static的解决方案:
1 . 应该尽量避免static成员变量引用资源耗费过多的实例,比如Context;
2 . Context尽量使用ApplicationContext,因为Application的Context的生命周期比较长,引用它不会出现内存泄漏的问题;
3 . 使用weakReference代替强引用。

线程导致内存溢出

  线程产生内存泄漏的主要原因在于线程生命周期的不可控。

  针对线程导致的内存泄漏问题的解决方案:
1 . 将线程的内部类,改为静态内部类(因为非静态内部类拥有外部类对象的强引用,而静态类则不拥有);
2 . 在线程内部采用弱引用保存Context引用;

如何避免OOM异常

图片过大导致的OOM

  Android中用bitmap时很容易内存溢出,会报错误:Java.lang.OutOfMemoryError:bitmap size exceeds VM budget。

  解决方法:
1 . 等比例缩小图片;

2 . 对图片采用软引用,及时地进行recycle()操作;

3 . 使用加载图片框架处理图片,因为这些第三方库都是做了相应的优化的;

界面切换导致OOM

  一般情况下,开发中都是禁止横屏的。因为如果横竖屏来回切换的话,又没有在AndroidManifest.xml文件中设置configChanges属性,Activity的生命周期会销毁后重新创建。所以可能就会造成来回横竖屏切换几次之后,就出现OOM了。
  这个问题没有固定的解决方法,一般我们从以下几个方面来分析:
1 . 看看页面布局中有没有大的图片,比如大的背景图,如果有的话,在布局.xml文件中去除;
2 . 在页面切换时尽可能少地重复使用一些代码;

查询数据库没有关闭Cursor游标导致OOM

  我们的程序中可能会进行查询数据库的操作,但是如果在查询完以后没有关闭cursor,如果又是大量操作的情况,就容易出现OOM。

构造Adapter时没有使用缓存convertView导致OOM

  在使用ListView的时候,我们通常会使用BaseAdapter,如果没有复用convertView,可能也会导致OOM。

Bitmap对象不再使用时未回收导致的OOM

  如果一个Bitmap对象比较占内存,当它不再被使用的时候,我们可以调用Bitmap.recycle()方法来回收此对象的像素所占用的内存。

其他情况

  比如在Activity的生命周期中没有合理地释放资源,比如广播没有注销。

-
-
-
-
-
-
-
-
-
-
-
-
-
-
---------------------last line for now---------------------