如何避免OOM

1、减少对象的内存占用html

1)使用更加轻量的数据结构

例如,咱们能够考虑使用ArrayMap/SparseArray而不是HashMap等传统数据结构。android

ArrayMap和HashMap主要不一样之处在于:数据库

一、存储方式不一样:ArrayMap内部使用两个数组,一个存HashCode,一个存键值对对象。HashMap内部是Entry对象。数组

二、扩容方式不一样:上面HashMap源码分析这篇文章说过了,HashMap初始大小是16,达到满容量的0.75时,要扩容,每次都是上次容量的2倍。缓存

 

ArrayMap用的是copy数据,因此效率相对要高。数据结构

 

最后说说使用场景,若是存储数量在千级如下,能够考虑用ArrayMap代替HashMap,但要注意的是,ArrayMap要比HashMap慢。Android里的Bundle内部就是ArrayMap,因此你们能够自行考虑使用。函数

2)避免在Android里面使用Enum

3)减少Bitmap对象的内存占用

4)使用更小的图片

2、内存对象的重复利用oop

 

1)复用系统自带的资源

2)注意在ListView/GridView等出现大量重复子组件的视图里对ConvertView的复用

4)避免在onDraw方法里面执行对象的建立源码分析

相似onDraw等频繁调用的方法,必定须要注意避免在这里作建立对象的操做,由于他会迅速增长内存的使用,并且很容易引发频繁的gc,甚至是内存抖动。性能

5)StringBuilder

在有些时候,代码中会须要使用到大量的字符串拼接的操做,这种时候有必要考虑使用StringBuilder来替代频繁的“+”。

避免对象的内存泄露

1)注意Activity的泄漏

内存对象的泄漏,会致使一些再也不使用的对象没法及时释放,这样一方面占用了宝贵的内存空间,很容易致使后续须要分配内存的时候,空闲空间不足而出现OOM。显然,这还使得每级Generation的内存区域可用空间变小,GC就会更容易被触发,容易出现内存抖动,从而引发性能问题。

一般来讲,Activity的泄漏是内存泄漏里面最严重的问题,它占用的内存多,影响面广,咱们须要特别注意如下两种状况致使的Activity泄漏: 

  • 内部类引用致使Activity的泄漏

最典型的场景是Handler致使的Activity泄漏,若是Handler中有延迟的任务或者是等待执行的任务队列过长,都有可能由于Handler继续执行而致使Activity发生泄漏。此时的引用关系链是Looper -> MessageQueue -> Message -> Handler -> Activity。为了解决这个问题,能够在UI退出以前,执行remove Handler消息队列中的消息与runnable对象。或者是使用Static + WeakReference的方式来达到断开Handler与Activity之间存在引用关系的目的。

  • Activity Context被传递到其余实例中,这可能致使自身被引用而发生泄漏。

内部类引发的泄漏不只仅会发生在Activity上,其余任何内部类出现的地方,都须要特别留意!咱们能够考虑尽可能使用static类型的内部类,同时使用WeakReference的机制来避免由于互相引用而出现的泄露。

2)考虑使用Application Context而不是Activity Context

对于大部分非必须使用Activity Context的状况(Dialog的Context就必须是Activity Context),咱们均可以考虑使用Application Context而不是Activity的Context,这样能够避免不经意的Activity泄露。

3)注意临时Bitmap对象的及时回收

虽然在大多数状况下,咱们会对Bitmap增长缓存机制,可是在某些时候,部分Bitmap是须要及时回收的。例如临时建立的某个相对比较大的bitmap对象,在通过变换获得新的bitmap对象以后,应该尽快回收原始的bitmap,这样可以更快释放原始bitmap所占用的空间。

须要特别留意的是Bitmap类里面提供的createBitmap()方法,如图所示:

  

这个函数返回的bitmap有可能和source bitmap是同一个,在回收的时候,须要特别检查source bitmap与return bitmap的引用是否相同,只有在不等的状况下,才可以执行source bitmap的recycle方法。

4)注意监听器的注销

在Android程序里面存在不少须要register与unregister的监听器,咱们须要确保在合适的时候及时unregister那些监听器。本身手动add的listener,须要记得及时remove这个listener。

5)注意缓存容器中的对象泄漏

有时候,咱们为了提升对象的复用性把某些对象放到缓存容器中,但是若是这些对象没有及时从容器中清除,也是有可能致使内存泄漏的。例如,针对2.3的系统,若是把drawable添加到缓存容器,由于drawable与View的强应用,很容易致使activity发生泄漏。而从4.0开始,就不存在这个问题。解决这个问题,须要对2.3系统上的缓存drawable作特殊封装,处理引用解绑的问题,避免泄漏的状况。

6)注意WebView的泄漏

Android中的WebView存在很大的兼容性问题,不只仅是Android系统版本的不一样对WebView产生很大的差别,另外不一样的厂商出货的ROM里面WebView也存在着很大的差别。更严重的是标准的WebView存在内存泄露的问题,因此一般根治这个问题的办法是为WebView开启另一个进程,经过AIDL与主进程进行通讯,WebView所在的进程能够根据业务的须要选择合适的时机进行销毁,从而达到内存的完整释放。

7)注意Cursor对象是否及时关闭

在程序中咱们常常会进行查询数据库的操做,但时常会存在不当心使用Cursor以后没有及时关闭的状况。这些Cursor的泄露,反复屡次出现的话会对内存管理产生很大的负面影响,咱们须要谨记对Cursor对象的及时关闭。

 

参考链接:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0920/3478.html