ART 与 Dalvik

码途织梦者
• 阅读 2629

首发于我的博客网站(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的运行速度。

ART 与 Dalvik

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/de...


欢迎大家来我的网站交流:般若程序蝉
ART 与 Dalvik

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
浪人 浪人
4年前
安卓内存优化
Android内存1.Android内存分配与回收机制从ApplicationFramework、Dalvik/Art、Linux内核三个部分来讲解关于Androd内存相关的知识(1)ApplicationFramework(https://imghelloworld.osscnbeijing.a
Java层逆向分析方法和技巧
本公众号分享的所有技术仅用于学习交流,请勿用于其他非法活动,如有错漏,欢迎留言指正Java层逆向分析方法和技巧一、smali汇编1.Dalvik字节码java字节码、Dalvik字节码、机器码之间的关系?在Android上,Java代码首先经过编译器编译成
Stella981 Stella981
3年前
SpringBoot学习:整合shiro自动登录功能(rememberMe记住我功能)
首先在shiro配置类中注入rememberMe管理器!复制代码(https://oscimg.oschina.net/oscnet/675f5689159acfa2c39c91f4df40a00ce0f.gif)/cookie对象;rememberMeCookie()方法是设置Cookie的生成模
Stella981 Stella981
3年前
Android里的Dalvik、ART、JIT、AOT有什么关系?
JIT,Justintime,即时编译,边运行边编译;AOT,AheadOfTime,提前编译,指运行前编译。区别  这两种编译方式的主要区别在于是否在“运行时”进行编译优劣JIT优点:  可以根据当前硬件情况实时编译生成最优机器指令(ps.AOT也可以做到,在用户使用时使用字节码根据机器情况在做一次编译)  可
Stella981 Stella981
3年前
KubeVela 正式开源:一个高可扩展的云原生应用平台与核心引擎
【来源:阿里巴巴云原生公众号(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzUzNzYxNjAzMg%3D%3D%26mid%3D2247496420%26idx%3D1%26sn%3D3c7f079c40fde0ea91
Easter79 Easter79
3年前
SpringBoot学习:整合shiro自动登录功能(rememberMe记住我功能)
首先在shiro配置类中注入rememberMe管理器!复制代码(https://oscimg.oschina.net/oscnet/675f5689159acfa2c39c91f4df40a00ce0f.gif)/cookie对象;rememberMeCookie()方法是设置Cookie的生成模
Stella981 Stella981
3年前
Apache Flink 介绍
本篇文章首发于我的微信公众号大数据技术和人工智能(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU2Njg5Nzk0NQ%3D%3D%26mid%3D2247483660%26idx%3D1%26sn%3Decf01
Stella981 Stella981
3年前
ART运行时无缝替换Dalvik虚拟机的过程分析
  Android4.4发布了一个ART运行时,准备用来替换掉之前一直使用的Dalvik虚拟机,希望籍此解决饱受诟病的性能问题。老罗不打算分析ART的实现原理,只是很有兴趣知道ART是如何无缝替换掉原来的Dalvik虚拟机的。毕竟在原来的系统中,大量的代码都是运行在Dalvik虚拟机里面的。开始觉得这个替换工作是挺复杂的,但是分析了相关代码之后,发现思路是
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
码途织梦者
码途织梦者
Lv1
江汉思归客,乾坤一腐儒
文章
3
粉丝
0
获赞
0