应用在使用过程中随着内存增加,当达到一定的条件后,GC开始工作,为新的对象释放出更多的内存,但是在GC过程中,任何其他在工作的线程会展厅,包括UI线程,频繁的GC会增加应用的卡顿情况,影响应用的流畅性,因此,要尽量减少系统GC行为,减小卡顿发生的概率。
优化内存的意义:
1.减少OOM,提高应用稳定性。
2.减少卡顿,提高应用流畅度。
3.减少内存占用,提高应用后台运行时的存活率。
4.减少异常发生,减少代码逻辑隐患。
●内存泄漏
内存泄漏是指应用已经不会再使用的内存对象,但垃圾回收时候没有把这些辨认出来,不能及时地回收,仍然一直保留在内存中。Android系统虚拟机的垃圾回收是通过虚拟机GC机制来实现的,GC会选择一些还存活的对象作为内存遍历的根节点GC Root,通过对GC Root的可达性来判断是否需要回收。没有被直接或间接遍历到的引用会被GC回收,能被遍历到的不能回收。
●常见内存泄漏场景
1.资源性对象未关闭
资源性对象,比如Cursor、File文件等如果仅仅把它的引用置为null,而不关闭他们,往往会造成内存泄漏,应该先调用close函数,然后再置为null。
2.注册对象未注销
如果事件注册后未注销,会导致观察者列表中维持着对象的引用,阻止垃圾回收,一般发生在注册广播接收器、注册观察者、注册EventBus等。假设在activity中注册了这些对象,在activity退出是忘记注销,则会导致activity无法被回收,如果不断进出这个activity,则最终会导致大量activity无法被回收而引起频繁的GC,甚至导致OOM。
3.类静态变量持有大数据对象
静态变量长期维持对象的引用,阻止垃圾回收,如果静态变量持有大数据对象时候,如bitmap等,就很容易引起内存不足等问题。
4.非静态内部类的静态实例
非静态内部类会维持一个到外部类实例的引用,如果非静态内部类的实例是静态的,就会长期维持着外部类的引用,阻止被系统回收。
5.Handler临时性内存泄漏
handler通过发送message和主线程交互,Message发出之后存储在MessageQueue中,有些message不会被马上处理到,在message中存在一个target,它是handler的一个引用,Message在Queue中存在时间过长,就会导致handler无法被回收,如果handler是非静态的,则会导致activity或者Service不会被回收。为了避免这种内存泄漏,可以使用一个静态的Handler内部类,然后对Handler持有的对象使用弱引用,在Activity的Destroy时,应该移除消息队列中的消息。
6.容器中的对象没有清理造成的内存泄漏
通常把一些对象的引用加入集合中,在不需要该对象时,如果没有把它的引用从集合中清理掉,这个集合就会越来越大,如果这个集合是static的,情况就更严重。
网友评论