Android内存管理机制

应用程序的内存分配和垃圾回收都是由Android虚拟机完成的

  • Android 5.0以下:Dalvik虚拟机
  • 5.0及以上:ART虚拟机

一、Android内存回收机制

在Android的高级系统版本中,针对Heap空间 Generational Heap Memory的模型,将整个内存分为三个区域:

  • Young Generation(年轻代)
  • Old Generation(年老代)
  • Permanent Generation(持久代)
  • Young Generation一个Eden区两个Survivor区组成,
  • Old Generation 通常状况下,年老代中的对象生命周期都比较长
  • Permanent Generation 用于存放静态的类和方法,持久代对垃圾回收没有显著影响。

          程序中生成的大部分新的对象都在Eden区中,当Eden区满时,还存活的对象将被复制到其中一个Survivor区S0区,当此S0区满时,该区域存活对象将复制到另外一个Survivor区S1区,而后S0清空,接下来S0和S1角色互换,当上面达到必定次数(系统版本不一样会有差别)后,存活对象将被复制到Old Generation,最后累积必定时间再移动到Permanent Generation区域。

二、不同区域GC使用的算法:

  • Young Generation:

        对象存活时间短,使用复制算法

        采用空闲指针的方式来控制GC触发,指针保持最后一个分配的对象在Young Generation区间的位置,当有新的对象要分配内存时,用于检查空间是否足够,不够就触发GC。

  • Old Generation:

        其对象存活时间较长,比较稳定,采用标记算法(扫描出存活的对象,而后再回收未被标记的对象,回收后对空出的空间要么合并,要么标记出来便于下次分配,以减小内存碎片带来的效率损耗)来回收。

三、在Android系统中,GC类型

  • kGcCauseForAlloc:分配内存不够引发的GC,会Stop World。因为是并发GC,其它线程都会中止,直到GC完成。
  • kGcCauseBackground:内存达到必定阈值触发的GC,因为是一个后台GC,因此不会引发Stop World。
  • kGcCauseExplicit:显示调用时进行的GC,当ART打开这个选项时,使用System.gc时会进行GC。

四、Android虚拟机中的GC日志

D/dalvikvm(7030):GC_CONCURRENT freed 1049K, 60% free 2341K/9351K, external 3502K/6261K, paused 3ms 3ms

分析:

GC时的类型:

  • GC_CONCURRENT:当应用程序中的Heap内存占用上升时(分配对象大小超过384k),避免Heap内存满了而触发的GC。若是发现有大量的GC_CONCURRENT出现,说明应用中可能一直有大于384k的对象被分配,而这通常都是一些临时对象被反复建立,多是对象复用不够所致使的
  • GC_FOR_MALLOC:这是因为Concurrent GC没有及时执行完,而应用又须要分配更多的内存,这时不得不停下来进行Malloc GC。
  • GC_EXTERNAL_ALLOC:这是为external分配的内存执行的GC。
  • GC_HPROF_DUMP_HEAP:建立一个HPROF profile的时候执行。
  • GC_EXPLICIT:显示调用了System.GC()。(尽可能避免)

  • freed 1049k:代表在此次GC中回收了多少内存。
  • 60% free 2341k/9351K:代表回收后60%的Heap可用,存活的对象大小为2341kb,Heap大小是9351kb。
  • external 3502/6261K:是Native Memory的数据。存放Bitmap Pixel Data(位图数据)或者堆之外内存(NIO Direct Buffer)之类的数据。第一个值说明在Native Memory中已分配3502kb内存,第二个值是一个浮动的GC阈值,当分配内存达到这个值时,会触发一次GC。
  • paused 3ms 3ms:代表GC的暂停时间,若是是Concurrent GC,会看到两个时间,一个开始,一个结束,且时间很短,若是是其余类型的GC,极可能只会看到一个时间,且这个时间是相对比较长的。而且,越大的Heap Size在GC时致使暂停的时间越长。

五、虚拟机的区别:

Dalvik

        GC的操做都是并发的,也就意味着每次触发GC都会致使其它线程暂停工做(包括UI线程)

ART

        GC时不像Dalvik仅有一种回收算法,ART在不一样的状况下会选择不一样的回收算法,好比Alloc内存不够时会采用非并发GC,但在Alloc后,发现内存达到必定阈值时又会触发并发GC。因此在ART模式下,并非全部的GC都是非并发的。

总结:在GC方面,与Dalvik相比,ART更为高效,不只仅是GC的效率,大大地缩短了Pause时间,并且在内存分配上对大内存分配单独的区域,还能有算法在后台作内存整理,减小内存碎片。所以,在ART虚拟机下,能够避免较多的相似GC致使的卡顿问题。

你可能感兴趣的:(Android:基础篇,android)