概述html
在android的开发中,要时刻主要内存的分配和垃圾回收,由于系统为每个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器通常都为24M,实在是少的可怜。这样就须要咱们在开发过程当中要时刻注意。不要由于本身的代码问题而形成OOM错误。java
JAVA的内存管理android
你们都知道,android应用层是由java开发的,android的davlik虚拟机与jvm也相似,只不过它是基于寄存器的。所以要了解android的内存管理就必须得了解java的内存分配和垃圾回收机制。算法
在java中,是经过new关键字来为对象分配内存的,而内存的释放是由垃圾收集器(GC)来回收的,工程师在开发的过程当中,不须要显式的去管理内存。可是这样有可能在不知不觉中就会浪费了不少内存,最终致使java虚拟机花费不少时间去进行垃圾回收,更严重的是形成JVM的OOM。所以,java工程师仍是有必要了解JAVA的内存分配和垃圾回收机制。
eclipse
内存结构jvm
上面这张图是JVM的结构图,它主要四个部分组成:Class Loader子系统和执行引擎,运行时方法区和本地方法区,咱们主要来看下RUNTIME DATA AREA区,也就是咱们常说的JVM内存。从图中能够看出,RUNTIMEDATA AREA区主要由5个部分组成:工具
Method Area:被装载的class的元信息存储在Method Area中,它是线程共享的google
Heap(堆):一个java虚拟机实例中只存在一个堆空间,存放一些对象信息,它是线程共享的spa
Java栈: java虚拟机直接对java栈进行两种操做,以帧为单位的压栈和出栈(非线程共享).net
程序计数器(非线程共享)
本地方法栈(非线程共享)
JVM的垃圾回收(GC)
JVM的垃圾原理是这样的,它把对象分为年轻代(Young)、年老代(Tenured)、持久代(Perm),对不一样生命周期的对象使用不一样的垃圾回收算法。
年轻代(Young)
年轻代分为三个区,一个eden区,两个Survivor区。程序中生成的大部分新的对象都在Eden区中,当Eden区满时,还存活的对象将被复制到其中一个Survivor区,当此Survivor区的对象占用空间满了时,此区存活的对象又被复制到另一个Survivor区,当这个Survivor区也满了的时候,从第一个Survivor区复制过来的而且此时还存活的对象,将被复制到年老代。
年老代(Tenured)
年老代存放的是上面年轻代复制过来的对象,也就是在年轻代中还存活的对象,而且区满了复制过来的。通常来讲,年老代中的对象生命周期都比较长。
持久代(Perm)
用于存放静态的类和方法,持久代对垃圾回收没有显著的影响。
Android中内存泄露监测
在了解了JVM的内存管理后,咱们再回过头来看看,在android中应该怎样来监测内存,从而看在应用中是否存在内存分配和垃圾回收问题而形成内存泄露状况。
在android中,有一个相对来讲还不错的工具,能够用来监测内存是否存在泄露状况:DDMS—Heap
使用方法比较简单:
选择DDMS视图,并打开Devices视图和Heap视图
点击选择要监控的进程,好比:上图中我选择的是system_process
选中Devices视图界面上的"update heap" 图标
点击Heap视图中的"Cause GC" 按钮(至关于向虚拟机发送了一次GC请求的操做)
在Heap视图中选择想要监控的Type,通常咱们会观察dataobject的 total size的变化,正常状况下total size的值会稳定在一个有限的范围内,也就说程序中的代码良好,没有形成程序中的对象不被回收的状况。若是代码中存在没有释放对象引用的状况,那么data object的total size在每次GC以后都不会有明显的回落,随着操做次数的增长而total size也在不断的增长。(说明:选择好data object后,不断的操做应用,这样才能够看出total size的变化)。若是totalsize确实是在不断增长而没有回落,说明程序中有没有被释放的资源引用。那么咱们应该怎么来定位呢?
Android中内存泄露定位
Mat(memory analyzer tools)是咱们经常使用的用来定位内存泄露的工具,若是你使用ADT,而且安装了MAT的eclipse插件,你须要作的是进入DDMS视图的Devices视图:
点击"dump HPROF file"按钮,而后使用MAT分析下载下来的文件。
下面列出了存在的问题,点击detail进去,会列出详细的,可能会存在问题的代码:
关于MAT的使用能够参考:http://www.blogjava.net/rosen/archive/2010/06/13/323522.html
这位兄弟写的比较详细。
总结
无论是java仍是android,都应该了解内存分配和垃圾回收机制,工程师要作到写的代码中没有bad code很难,关键是在出现问题的时候该怎么去排查。