android ART
ART(Android Runtime)
是Android5.0以后所使用的一种新的虚拟机。ART采用Ahead-of-time(AOT:Android系统自带的dex2oat工具把APK里面的.dex文件转化成OAT文件,OAT文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容)技术,
应用在第一次安装的时候,字节码就会预先编译成本地机器码,之后每次打开应用,执行的都是本地机器码,去除了运行时的解释执行,效率更高,启动更快(运行时内存占用空间较少同样意味着编译二进制需要更高的存储)。
ART同时也改善了性能、垃圾回收(Garbage Collection)、应用程序除错以及性能分析
ART运行时内部使用的Java堆的主要组成包括:
四个Space:Image Space、Zygote Space、Allocation Space、Large Object Space
两个Mod Union Table
一个Card Table
两个Heap Bitmap:Live Bitmap、Mark Bitmap
两个Object Map:Live Object Map、 Mark Object Map
三个Object Stack:Live Stack、Mark Stack、Allocation Stack
Image Space
是不能分配新对象的
Image Space和Zygote Space在Zygote进程和应用程序进程之间进行共享,
Allocation Space
每个进程都独立地拥有一份
Mod Union Table对象:
一个用来记录在GC并行阶段在Image Space上分配的对象对在Zygote Space和Allocation Space上分配的对象的引用。
另一个用来记录在GC并行阶段在Zygote Space上分配的对象对在Allocation Space上分配的对象的引用。
Allocation Stack:
用来记录上一次GC后分配的对象,用来实现类型为Sticky的Mark Sweep Collector。
Live Stack:
配合allocation_stack_一起使用,用来实现类型为Sticky的Mark Sweep Collector。
Mark Stack:
用来在GC过程中实现递归对象标记
Image Space和Zygote Space之间
隔着一段用来映射system@framework@boot.art@classes.oat文件的内存。
system@framework@boot.art@classes.oat是一个OAT文件,它是由系统启动类路径中的所有DEX文件翻译得到的,
Image Space映射的是一个system@framework@boot.art@classes.dex文件,这个文件保存的是在生成system@framework@boot.art@classes.oat这个OAT文件的时候需要预加载的类对象
(需要预加载的类由/system/framework/framework.jar文件里面的preloaded-classes文件指定)。
以后只要系统启动类路径中的DEX文件不发生变化(即不发生更新升级),那么以后每次系统启动只需要将文件system@framework@boot.art@classes.dex直接映射到内存即可。
由于system@framework@boot.art@classes.dex文件保存的是一些预先创建的对象,并且这些对象之间可能会互相引用,
因此须保证system@framework@boot.art@classes.dex文件每次加载到内存的地址都是固定的(这个固定的地址保存在system@framework@boot.art@classes.dex文件开头的一个Image Header中。
此外system@framework@boot.art@classes.dex文件也依赖于system@framework@boot.art@classes.oat文件,因此也会将后者固定加载到Image Space的末尾。
Image Space <–> system@framework@boot.art@classes.dex // 它为system@framework@boot.art@classes.oat文件需预加载的类对象
//系统启动类路径中的DEX文件不发生变化,则每次系统启动只需将文件system@framework@boot.art@classes.dex直接映射到内存即可,须确保加载到内存的地址都是固定,该地址存放于一个Image Header中
|
v
system@framework@boot.art@classes.oat //系统启动类路径中的所有DEX文件翻译得到,固定加载到Image Space的末尾
|
v
Zygote Space
ART运行时对象的创建:
可分配内存的Space有三个:Zygote Space、Allocation Space和Large Object Space
Zygote Space在还没有划分出Allocation Space之前,就在Zygote Space上分配,
而当Zygote Space划分出Allocation Space之后,就只能在Allocation Space上分配。因此实际上应用运行的时候能够分配内存也就Allocation Space和Large Object Space。
而分配的对象究竟是存入上面的哪个Space呢?满足如下三个条件的内存,存入Large Object Space:
1、Zygote Space已经划分除了Allocation Space,
2、分配对象是原子类型数组,如int[] byte[] boolean[],
3、分配的内存大小大于一定的门限值。
对于分配对象时内存不足的问题,是通过垃圾回收和在允许范围内增长堆大小解决的。由于垃圾回收会影响程序,因此ART运行时采用力度从小到大的进垃圾回收策略。
一旦力度小的垃圾回收执行过后能满足分配要求,那就不需要进行力度大的垃圾回收了(跟dalvik虚拟机的对象分配策略也是类似的)。
ART的运行原理:
1、Android系统启动过程中创建的Zygote进程利用ART运行时导出的Java虚拟机接口创建ART虚拟机。
2、APK在安装的时候,里面的classes.dex文件会被工具dex2oat翻译成本地机器指令,最终得到一个ELF格式的oat文件。
3、APK运行时,生成的oat文件会被加载到内存,并且ART虚拟机可以通过里面的oatdata和oatexec段找到任意一个类的方法对应的本地机器指令来执行。
—oat文件中的oatdata包含用来生成本地机器指令的dex文件内容
—oat文件中的oatexec包含有生成的本地机器指令。
ART中查找类和方法:
1、在DEX文件中找到目标DEX类的编号,并且以这个编号为索引,在OAT文件中找到对应的OAT类。
2、在DEX文件中找到目标DEX方法的编号,并且以这个编号为索引,在上一步找到的OAT类中找到对应的OAT方法。
3、使用找到的OAT方法的成员变量begin_和code_offset_,计算出该方法对应的本地机器指令
说明:
DEX文件中的类和方法称之为DEX类和DEX方法,
OTA中的类和方法称之为OTA类和OTA方法,
ART运行时将类和方法称之为Class和ArtMethod。
ART中一个已经加载的Class对象包含了一系列的ArtField对象和ArtMethod对象:
ArtField对象用来描述成员变量信息
ArtMethod用来描述成员函数信息对于每一个ArtMethod对象,它都有一个解释器入口点和一个本地机器指令入口点