Android dex(关于Dalvik、ART、DEX、ODEX、JIT、AOT、OAT)

Posted by Jfson on 2019-07-03

疑问:class,dex,odex,vdex的区别?

参考文章

android-art-googlt-doc

Android 8.0 VDEX机制简介

关于Dalvik、ART、DEX、ODEX、JIT、AOT、OAT

art

  • 1.art

Android Runtime (ART) 是运行 Android 5.0(API 级别 21)及更高版本的设备的默认运行时。ART 使用设备自带的 dex2oat 工具来编译应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
预先 (AOT) 编译
ART 引入了预先编译机制,可提高应用的性能。ART 还具有比 Dalvik 更严格的安装时验证。
在安装时,ART 使用设备自带的 dex2oat 工具来编译应用。该实用工具接受 DEX 文件作为输入,并为目标设备生成经过编译的应用可执行文件。该工具应能够顺利编译所有有效的 DEX 文件。但是,一些后处理工具会生成无效文件,Dalvik 可以接受这些文件,但 ART 无法编译这些文件。有关详情,请参阅解决垃圾回收问题。
垃圾回收方面的优化
垃圾回收 (GC) 可能有损于应用性能,从而导致显示不稳定、界面响应速度缓慢以及其他问题。ART 通过以下几种方式对垃圾回收做了优化:
只有一次(而非两次)GC 暂停
在 GC 保持暂停状态期间并行处理
在清理最近分配的短时对象这种特殊情况中,回收器的总 GC 时间更短
优化了垃圾回收的工效,能够更加及时地进行并行垃圾回收,这使得 GC_FOR_ALLOC 事件在典型用例中极为罕见
压缩 GC 以减少后台内存使用和碎片
开发和调试方面的优化
ART 提供了大量功能来优化应用开发和调试。
  • 2.JIT
  • ART 使用预先 (AOT) 编译,并且从 Android 7.0(代号 Nougat,简称 N)开始结合使用 AOT、即时 (JIT) 编译和配置文件引导型编译。所有这些编译模式的组合均可配置,我们将在本部分中对此进行介绍。例如,Pixel 设备配置了以下编译流程:

    • 最初安装应用时不进行任何 AOT 编译。应用前几次运行时,系统会对其进行解译,并对经常执行的方法进行 JIT 编译。
    • 当设备闲置和充电时,编译守护进程会运行,以便根据在应用前几次运行期间生成的配置文件对常用代码进行 AOT 编译。
    • 下一次重新启动应用时将会使用配置文件引导型代码,并避免在运行时对已经过编译的方法进行 JIT 编译。在应用后续运行期间进行了 JIT 编译的方法将会被添加到配置文件中,然后编译守护进程将会对这些方法进行 AOT 编译。
  • 3.ART 包括一个编译器(dex2oat 工具)和一个为启动 Zygote 而加载的运行时 (libart.so)。dex2oat 工具接受一个 APK 文件,并生成一个或多个编译工件文件,然后运行时将会加载这些文件。文件的个数、扩展名和名称会因版本而异,但在 Android O 版本中,将会生成以下文件:

    • .vdex:其中包含 APK 的未压缩 DEX 代码,另外还有一些旨在加快验证速度的元数据。
    • .odex:其中包含 APK 中已经过 AOT 编译的方法代码。
    • .art (optional):其中包含 APK 中列出的某些字符串和类的 ART 内部表示,用于加快应用启动速度。

2.总结

看了引用文章写的模棱两可,不明不白的,那我们来总结一下这几个家伙到底是干什么的,以及出现的timeline

  • a. Android L( 5.0 ) 引入Android Runtime (ART)
    • ART 引入了预先编译机制,ART 使用设备自带的 dex2oat 工具来编译应用,提高启动速度
    • 垃圾回收方面的优化
  • odex 怎么来的
    • ART : .dex->.odex(机器码)(AOT Ahead-Of-Time)
    • Dalvik: .dex->.odex(字节码)(JIT Just-In-Time)
    • 机器码可直接执行,而字节码每次启动都需要执行将优化过的odex字节码再转换成机器码
  • c.Android O ( 8.0 ) 引入了vdex机制
    • 目的是为了降低dex2oat时间。做dex2oat,如果有vdex的话,就可以省去重新校验apk里dex文件合法性的过程 。从而优化了开机速度

3.引申

  • Android8.0引入的vdex?

目的不是为了提升性能,而是为了避免不必要的验证Dex 文件合法性的过程,例如首次安装时进行dex2oat时会校验Dex 文件各个section的合法性,这时候使用的compiler filter 为了照顾安装速度等方面,并没有采用全量编译,当app盘启动后,运行一段时间后,收集了足够多的jit 热点方法信息,Android会在后台重新进行dex2oat, 将热点方法编译成机器代码,这时候就不用再重复做验证Dex文件的过程了,我测试了下,例如支付宝淘宝这类Dex文件比较大的app在Nexus 5X上大概可以节省2秒左右时间。============具体可以看下Google的commit信息:

1
2
3
4
5
6
7
Introduce VDEX file, use it for DEX filesThis patch introduces a new output file called VDEX.
In the future,VDEX files will store pre-validated DEX files which do not need to bere-extracted and re-verified when recompiling, e.g.
due to newprofiling information or after a system update.With this CL,
the OatWriter writes DEX files into the VDEX and therest of its output into OAT.
The OatFile class and related classesare updated to load the VDEX at runtime and mmap the DEX file sectionfrom it.
Patchoat creates symlinks to the source VDEX files in thetarget directory or copies the files if passed in as file descriptors.
The feature can be disabled by setting the environment variableART_ENABLE_VDEX to false.

pv UV: