基本概念
dex: app 代码执行文件
dex2oat: Art 的编译工具进程,将dex文件编译成OAT 文件。
OAT文件:
Android运行时ART的核心是OAT文件。OAT文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容。这样无需重新编译原有的APK就可以让它正常地在ART里面运行,也就是我们不需要改变原来的APK编程接口。
tinker: app 热修复的补丁
Android APK 大部分使用 JAVA 语言编写,与编译执行语言不同的是,APK 字节码需要被翻译成机器可识别的机器码才能被执行,这个过程是影响 APK 运行速度及流畅度的一个因素。在当前 Android 运行环境中,字节码被翻译发生在以下 3 个地方:
解释执行:解释器接收指令,转换成机器码,其结果仅当次有效。若存在大量解释执行,则运行速度慢 (比如执行循环时存在重复解释)。
JIT (Just-in-time compilation):Art 虚拟机通过记录方法的被调用次数,将热方法翻译得到的机器码缓存起来,当下次再调用时可直接使用,速度快且能根据上下文进一步优化速度,但仅当前进程有效,缓存占有限内存空间。
AOT (Ahead-of-time compilation):在 APK 运行前,通过 dex2oat 提前将字节码编译成机器码保存在 odex 文件中,当运行时可直接加载其中的机器码执行,速度快,但编译有额外耗时,odex 占空间。
当前的 ART虚拟机结合了以上 3 种方式,并通过一种 profile-guide AOT 的机制,在 APK 运行速度、安装耗时、 空间占用大小 到达一个平衡:
1- APK 初始安装时,仅 AOT 编译部分 JNI 方法,这样安装速度快,空间占用小;
2- 在 APK 的运行过程中,JIT 会记录热方法到 profile 文件中。
3- 当手机处于空闲状态时,dex2oat 根据 profile 提前将常用方法编译到 odex 文件中,下次运行时能够直接使用,这样 APK 越用越快。
Android 进化史:
Android 2.3 比较稳定的一个版本
Android 4.4 google推出的新型的模式——ART(Android RunTime)模式,彼时 ART 是和 Dalvik 共存的。
Android 5.0 —— ART 全面取代 Dalvik, AOT 也成为唯一的编译模式,AOT是全量编译,
Android 7.0 —— JIT 回归,形成 AOT/JIT 混合编译模式。
触发dex 编译分为2个场景:
安装应用,app自升级,系统编译,都会经过 installd 去fork dex2oat 编译。
App 去调用 dex2oat 编译 dex 文件。
不过在Android10之后这一点有了修改,Android 运行时 (ART) 不再从应用进程调用 dex2oat。这项变更意味着 ART 将仅接受系统生成的 OAT 文件。