Android内存管理

   今天提出了辞职,忽然感觉轻松了许多,写下此篇文章。

   Android的整个系统架构分为应用层、应用框架层、类库和运行时以及内核层,应用层和应用框架层是使用java语言进行开发的,而library和runtime则是使用c类的语言进行开发。jvm有自动的垃圾回收机制,所以很多的开发者在使用java语言时并不会过多的去关注内存使用问题。

   但是Android开发人员就不得不去关心这个问题了。Android采用沙箱的机制隔离每个应用,每个应用运行在自己独立的环境当中,单个应用的出生和死亡不会影响到其他的应用的运行。再者Android系统默认为每个应用默认分配16M的内存空间,一旦这个内存使用完毕,而内存空间没有得到释放,就会使得Android应用崩溃,出现臭名昭著的OOM异常,所以要聊Android内存管理就必须从OOM开始。

   本文将会从OOM、避免内存泄露、代码优化和图片内存管理来讲解。

一、OOM介绍:

   Android应用在运行的的时候,系统限制了每个应用运行时可使用的内存大小,可是在Android中不存在swap分区的概念,所以说唯一能够腾出内存的地方只有释放对象的引用。一旦引用不能及时释放,造成内存紧张就可能会导致OOM异常。所以OOM异常可以总结为当应用在heap(Android虚拟机以上的消耗)中所占用的内存达到能够使用的上限时候,虚拟机抛出的异常。如果想增加每个应用使用内存的上限,可以通过在清单文件中加上largeHeap=true,但是这种方式也有一定的上限。

二、内存泄露:

   内存泄露指的是申请过的内存空间使用完毕后不再使用,但是这个内存资源却没有得到及时的释放。内存泄露之后我们唯一能做的只能催促虚拟机快点去回收内存,其他的我们是不能干预的。我们能做的只有避免内存泄露。

   1、引用和GC

     就是说某一块占用内存很大的对象没有得到正确释放,所以就算我们在一个方法运行未结束,之前不使用的对象我们进行的释放掉。

   2、Android应用进程策略

    在Android中,应用进程是不会随着四大组件的消亡而消亡,就算所有的Activity都销毁了,就算这个进程是个空进程,这个进程可能还会存在。所以这也就导致了一个问题,在代码中我们经常的使用static静态变量,静态变量是属于类变量,是所有的类共享的变量,就算应用进程还在,这个变量就会一直存在,如果说这个类是个Activity,当这个Activity销毁之后,就会造成内存的泄露。所以尽量的不要去给某个Activity中的变量设置类变量。
    可能会有朋友讲如果要在一个Activity B中使用另外一个Activity A的变量怎么办呢?一般的做法是这样的将A中的变量设置为static,然后在B中直接访问,上面讲述了这种办法实不可取的。我在这里给大家介绍一个办法就是使用application,可以在A中使用myApplication.setData(list.clone())进行存储。在B中可以myApplication.getData()获取到变量,这样使用Application进行数据的传可以防止内存泄露。可能有朋友又要问了这里为什么使用list.clone()呢,因为如果这里不使用克隆的话,就会造成B持有A中list的引用,造成A不能及时的销毁。

   3、Activity与Context内存泄露

     当我们在一个Activity中启动另外一个Activity的时候一般是这样写的
     
        Intent a = new Intent(this,B.class);
        startActivity(a);
     这样B会持有这个context的引用,也会导致A不能及时消亡。
     还有一种情况就是横竖屏切换的时候,Activity A会重建,不能及时释放原来的A,如果此时A中持有B类中的对象引用,会造成内存中存在两份A
     所以很多地方用到上下文的时候能使用ApplicationContext代替的地方就代替。

   4、Activity与Handler内存泄露

     当A利用handler发送一个message后,message会被主线程中的消息队列所持有,如果此时A退出,但是message还未被处理响应,那么A就不能被及时的释放,从而造成内存泄露。
   其他的避免内存泄露还有诸如及时的解除引用、正确利用cursor、及时解绑已经注册的广播等等

此文暂时写到这里,待会继续!


      

      

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。