这是我参与「第四届青训营 」笔记创作活动的第5天
今天我们着重对 ART 虚拟机的知识进行一个整理,其中涉及到Android整体架构和ART架构,当然也包括java对象与ART执行的一些方式进行了说明。
对象
在本次课程中主要讲述了对象分配出来的原理,对对象分配的大小、内存分配和内存回收都作了一个说明。当我们通过new创建一个Java对象时,虚拟机会安排内存分配的所有工作。在我们创建一个Java对象时,也会伴随着java.lang.Object的实例化过程。此外Java中提供了一个java.lang.Class类,该类的实例表示一个运行程序中的类或接口,实例中的字段记录了类或接口的元数据。
下图是对象和类之间的一个关系:
内存分配
分配算法的实现:这里主要记录Buddy算法的实现。假如系统需要4(2 * 2)个页面大小的内存块,该算法就到free_area[2]中查找,如果链表中有空闲块,就直接从中摘下并分配出去。如果没有,算法将顺着数组向上查找free_area[3],如果free_area[3]中有空闲块,则将其从链表中摘下,分成等大小的两部分,前四个页面作为一个块插入free_area[2],后4个页面分配出去,free_area[3]中也没有,就再向上查找,如果free_area[4]中有,就将这16(2 * 2 * 2 * 2)个页面等分成两份,前一半挂如free_area[3]的链表头部,后一半的8个页等分成两等分,前一半挂free_area[2]
的链表中,后一半分配出去。假如free_area[4]也没有,则重复上面的过程,知道到达free_area数组的最后,如果还没有则放弃分配。
内存释放原理:内存的释放是分配的逆过程,也可以看作是伙伴的合并过程。当释放一个块时,先在其对应的链表中考查是否有伙伴存在,如果没有伙伴块,就直接把要释放的块挂入链表头;如果有,则从链表中摘下伙伴,合并成一个大块,然后继续考察合并后的块在更大一级链表中是否有伙伴存在,直到不能合并或者已经合并到了最大的块(2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2个页面)。
内存回收
回收算法的实现:主流的大部分Davik采取的都是标注与清理(Mark and Sweep)回收算法,也有实现了拷贝GC的,这一点和HotSpot是不一样的,具体使用什么算法是在编译期决定的,无法在运行的时候动态更换。如果在编译dalvik虚拟机的命令中指明了"WITH_COPYING_GC"选项,则编译"/dalvik/vm/alloc/Copying.cpp"源码 – 此是Android中拷贝GC算法的实现,否则编译"/dalvik/vm/alloc/HeapSource.cpp" – 其实现了标注与清理GC算法。
由于Mark and Sweep算法的缺点,容易导致内存碎片,所以在这个算法下,当我们有大量不连续小内存的时候,再分配一个较大对象时,还是会非常容易导致GC.
本次课程对于ART虚拟机的内存分配与回收机制都作了一个较为详尽的介绍,ART虚拟机给APP和system server进程提供运行环境,包括JAVA语法支持,托管,性能优化,debug等等一系列的能力,也是Android开发当中必不可少的一部分。