ART工作流程及特性

首发于我的博客网站(prajna.top) 欢迎大家前去交流,有pdf版本。


ART (Android Runtime)是运行于 Android 5.0(API 21)及以上的默认运行时环境,用来替换Dalvik,它大大提升了 Android 平台和应用的性能和流畅度。ART兼容Dalvik,能运行它的字节码,它的启用是系统默认的,不需要做什么配置,可以通过调System.getProperty (“java.vm.version”) 来验证正在使用哪种运行时。

  • ART -- “2.0.0” 或更高
  • Dalvik -- 小于 “2.0.0”

ART工作流程

ART使用 AOT和JIT对APK进行编译,生成的代码是基于profile来配置的,它的基本流程如下:

  1. 如果应用没有被预编译成AOT码,它在最初的几次运行中,经常使用的“方法”会被JIT编译。
  2. 系统空闲的时候,会调用AOT来编译apk经常被使用的代码。
  3. 当app再次运行的时候,它会优先使用被编译的代码(AOT或者GIT码)。

Ahead-of-time (AOT) 编译

ART会运行dex2oat命令来把DEX转换成下面几类文件(以Android O 为例)。

  • vdex : 包含未压缩的dex码和一些能加速校验的元数据。
  • odex : 优化的dex码 -- apk的“方法”代码会被AOT编译。
  • art : 把APK的字符串和类的列表转换成ART内部格式,用来加速应用的启动。
  • oat : 编译生成的OAT码,是一个ELF的可执行文件, 一般预编译在ROM里。

如:dex2oat --compiler-filter=speed --dex-file=xx.apk –oat-file=xx.oat,将生成 .oat 和 .vdex文件。

编译选项

ART有两类配置:

  1. ROM系统配置:ART在编译系统image的时候,对apk进行预编译。
  2. 运行时配置:ART在应用运行的时候,对apk进行编译。

最核心的一个编译选项是 “编译过滤器”,它也会被作为参数传给dex2oat,Android O版本一共支持4类过滤器:

  • verify: 运行 DEX代码校验。
  • quicken: 运行 DEX代码校验,优化一些指令,提高指令解释性能。
  • speed: 运行 DEX代码校验,AOT编译所有的方法。
  • speed-profile: 运行 DEX代码校验,AOT编译profile指定的方法。

系统ROM配置

需要编译到系统ROM的JAR/APK一共有4类:

  • Boot classpath 的代码: 缺省使用speed过滤器编译。
  • 系统服务的代码: 缺省使用speed过滤器编译。
  • 配置为“核心”的应用: 缺省使用speed过滤器编译。
  • 其它应用: 缺省使用quicken过滤器编译。

Makefile options

  • WITH_DEXPREOPT: 编译ROM时优化,默认启用。
  • DONT_DEXPREOPT_PREBUILTS:不进行预编译优化。
  • LOCAL_DEX_PREOP: [true/false],配置APK是否编译优化。
  • PRODUCT_DEXPREOPT_SPEED_APPS: 产品的core应用列表。
  • PRODUCT_SYSTEM_SERVER_APPS: 系统服务加载的app。

运行时配置

Jit options

  • dalvik.vm.usejit: 是否启用git编译[true/false]。
  • dalvik.vm.jitinitialsize (default 64K)。
  • dalvik.vm.jitmaxsize (default 64M)。
  • dalvik.vm.usejitprofiles:是否启用 profile [true/false]。

包管理配置

下面都是系统属性,用来设置各种情况下的编译过滤器。

  • pm.dexopt.install=quicken -- 从googplay安装app时的编译过虑器。
  • pm.dexopt.bg-dexopt=speed-profile -- 系统空闲时的编译过滤器。
  • pm.dexopt.boot=verify -- 系统在线升级后的编译过滤器(强烈推荐此配置)。
  • pm.dexopt.first-boot=quicken -- 第一次启动的编译过滤器。

JIT编译器

JIT主要时用于“运行时”的编译--也就时“及时/在线”编译,ART编译器在编译ROM的时候,会根据配置把预置的app编译成oat文件,但是,为了节省存储空间,有些app不做预编译,另外,系统更新,用户下载的app也没法做预编译优化,这种情况下,JIT就派上用场了,它的工作流程是:

  • ART运行app,解释执行dex码。
  • 如果是频繁运行的代码,ART调用JIT来编译这部分代码,并加入到JIT代码缓存中。
  • 再次运行这部分代码时,ART直接运行JIT的缓存代码,而不是解释执行dex码。
  • app继续运行。

整个流程如下图所示,可见JIT是ART编译器的一个补充,通过“在线”编译“热代码”的方式来优化app的运行速度。

在这里插入图片描述

Dalvik APK兼容性校验

虽然ART兼容Dalvik,但是仍然有少量不兼容,不支持的特性,需要对代码做些检查。

垃圾回收问题

ART中不必要显式调用 System.gc() 来促进垃圾回收 (GC)。
Get…ArrayElements()-- dalvik 返回的是reference,art 返回的是copy。

堆栈

Dalvik的 native堆栈(缺省1MB) 和 Java的堆栈(缺省32KB)是分开的,ART的堆栈是统一的。 如果你设置过堆栈,需要做些检查。

  • java 层检查Thread
  • C/C++检查 pthread_attr_setstack, pthread_attr_setstacksize,…

参考资料

https://source.android.com/devices/tech/dalvik/configure


欢迎大家来我的网站交流: 般若程序蝉
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值