Android ART 虚拟机学习(一) -- 框架/模块
作者:FloatingGuy 转载请注明出处:https://floatingguy.github.io/
学习老罗的文章,简单记录一下
Android运行时ART简要介绍和学习计划
Dalvik
JIT (just in time)执行本地机器指令
尽管Dalvik也会对频繁执行的代码进行JIT生成本地机器指令来执行,但毕竟在应用程序运行的过程中将Dex字节码翻译成本地机器指令也会影响到应用程序本身的执行,因此即使Dalvik使用了JIT,也在一定程度上也比不上直接就可以执行本地机器指令的运行时。
ART
Java 虚拟机接口 + 垃圾回收
APK 安装时走 AOT 流程
AOT(Ahead of Time)相对 Jit而言。AOT 要求 apk 安装时就要编译成本地机器指令。
LLVM
在ART中,打包在APK里面的Dex字节码是通过LLVM翻译成本地机器指令的。LLVM是一个用来快速开发自己的编译器的框架系统。
基于LLVM架构开发的编译器的执行过程如图2所示
前端工具:对输入的源代码(Source Code)进行语法分析后,生成一棵抽象语法树(Abstract Syntax Tree,AST),并且可以进一步将得到的抽象语法树转化一种称为LLVM IR的中间语言。LLVM IR是一种与编程语言无关的中间语言
优化器:优化器对LLVM IR文件进行优化,例如消除代码里面的冗余计算
- 后端工具:后端负责生成最终的机器指令。
dalvik 优化 dex 到 odex
APK在安装的时候,安装服务PackageManagerService会通过守护进程installd调用一个工具dexopt对打包在APK里面包含有Dex字节码的classes.dex进行优化,优化得到的文件保存在/data/dalvik-cache目录中,并且以.odex为后缀名,表示这是一个优化过的Dex文件。
art 优化 dex 到本地机器指令 (还保存为以前的 odex 文件)
在ART运行时中,APK在安装的时候,同样安装服务PackageManagerService会通过守护进程installd调用另外一个工具dex2oat对打包在APK里面包含有Dex字节码进翻译。这个翻译器实际上就是基于LLVM架构实现的一个编译器,它的前端是一个Dex语法分析器。翻译后得到的是一个ELF格式的oat文件,这个oat文件同样是以.odex后缀结束,并且也是保存在/data/dalvik-cache目录中。
oat 文件格式
oat 比正常的 ELF 可执行文件多了 oatdata 和 oatexec段。
- oatdata 段 保存apk 中原始的 dex 文件
- oatexec 段 保存翻译过后的 机器指令
后续内容:
ART加载oat文件的过程。
ART查找类和方法的过程。
ART查找类方法的本地机器指令的过程。
Dalvik虚拟机的垃圾收集过程。
ART的垃圾收集过程。
Android ART运行时无缝替换Dalvik虚拟机的过程分析
本文主要 结合源代码分析 art 替换 dalvik 需要做的工作。
总结下来就2部分:
- 创建虚拟机 ART 虚拟机
- 将dex 翻译成 oat 的过程
创建虚拟机 ART 虚拟机
这个过程要从 系统启动开始。
回忆一下 dalvik 虚拟的创建过程,是由 Zygote 进程完成,之后的所有进程都是从 zygote 孵化而来。
将dex 翻译成 oat 的过程
- 在安装 apk 时会进行一次对待安装 app 的翻译
- 在系统启动时,会对 /system/app 、/data/app、/system/framework 目录下的 apk 或者 jar 文件,以及这些 APK 所引用的外部 JAR,进行 dex 到 oat 的翻译。
上述2条翻译的路线都是从 PMS 开始,最后一直到生成 odex文件结束。