前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Android N 中的ART

Android N 中的ART

作者头像
用户9732312
发布于 2022-05-13 09:58:38
发布于 2022-05-13 09:58:38
1K00
代码可运行
举报
文章被收录于专栏:ADAS性能优化ADAS性能优化
运行总次数:0
代码可运行

我们知道在Android N 中对其 ART做了比较大的变化。主要是同一程序的代码可能同时运行在本地机器码(编译)、解释和JIT(Just In Time)的混合运行模式,并且不同的用户,同一应用程序的代码,可能运行不同的编译代码。因为有了Profile-guided JIT/AOT Compilation,那么不同的用户行为对同一app可能会有不同的编译结果。N 上做此变化的其目的是为了在安装时间、内存占用、电池消耗和性能之间获得最好的折衷。

ART是在Android KitKat引入并在Lollipop中设为默认的运行方式。ART的主要特征之一就是安装时对应用的AOT编译。这种方式的主要优点就是优化产生的本地代码性能更好,执行起来需要更少的电量。劣势在于安装文件所需的空间和时间。在Lollipop和Marshmallow(译者注:Android 6.0)中,大的应用需要数分钟才能安装完。为了改变这种状态,Android N实现了一个混合模式的运行环境。应用在安装时不做编译,而是解释字节码,所以可以快速启动。ART中有一种新的、更快的解释器,通过一种新的JIT完成,但是这种JIT的信息不是持久化的。取而代之的是,代码在执行期间被分析,分析结果保存起来。然后,当设备idle和充电的时候,ART会执行针对“热代码”进行AOT编译,其他代码不做编译。为了得到更优的代码,ART采用了几种技巧包括深度内联。

对同一个应用可以编译数次,或者找到变“热”的代码路径或者对已经编译的代码进行新的优化,这取决于分析器在随后的执行中的分析数据。

这种混合使用AOT、解释、JIT的策略有如下优点:

  • 即使是大应用,安装时间也能缩短到几秒
  • 系统升级能更快地安装,因为不再需要优化这一步
  • 应用的内存占用更小,有些情况下可以降低50%
  • 改善了性能
  • 更低的电池消耗

JIT architecture

JIT compilation works in this manner:

  1. The user runs the app, which then triggers ART to load the .dex file.
  2. If the .oat file (the AOT binary for the .dex file) is available, ART uses them directly. Note that .oat files are generated regularly. However, that does not imply they contain compiled code (AOT binary).
  3. If no .oat file is available, ART runs through either JIT or an interpreter to execute the .dex file. ART will always use the .oat files if available. Otherwise, it will use the APK and extract it in memory to get to the .dex incurring a big memory overhead (equal to the size of the dex files).
  4. JIT is enabled for any application that is not compiled according to the "speed" compilation filter (which says, compile as much as you can from the app).
  5. The JIT profile data is dumped to a file in a system directory. Only the application has access to the directory.
  6. The AOT compilation (dex2oat) daemon parses that file to drive its compilation.

Android N的编译模式

compiler_filter.h,我们可以看到dex2oat一共有12种编译模式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
enum Filter {   
    VerifyNone,           // Skip verification but mark all classes as verified anyway.
    kVerifyAtRuntime,     // Delay verication to runtime, do not compile anything.
    kVerifyProfile,       // Verify only the classes in the profile, compile only JNI stubs.
    kInterpretOnly,       // Verify everything, compile only JNI stubs.
    kTime,                // Compile methods, but minimize compilation time.
    kSpaceProfile,        // Maximize space savings based on profile.
    kSpace,               // Maximize space savings.
    kBalanced,            // Good performance return on compilation investment.
    kSpeedProfile,        // Maximize runtime performance based on profile.
    kSpeed,               // Maximize runtime performance.
    kEverythingProfile,   // Compile everything capable of being compiled based on profile.
    kEverything,          // Compile everything capable of being compiled.
};

以上12种编译模式按照排列次序逐渐增强,那系统默认采用了哪些编译模式呢?我们可以在在手机上执行getprop | grep pm查看:

pm.dexopt.ab-ota: [speed-profile] pm.dexopt.bg-dexopt: [speed-profile] pm.dexopt.boot: [verify-profile] pm.dexopt.core-app: [speed] pm.dexopt.first-boot: [interpret-only] pm.dexopt.forced-dexopt: [speed] pm.dexopt.install: [interpret-only] pm.dexopt.nsys-library: [speed] pm.dexopt.shared-apk: [speed]

其含义如下,

  1. install(应用安装)与first-boot(应用首次启动)使用的是[interpret-only],即只verify,代码解释执行即不编译任何的机器码,它的性能与Dalvik时完全一致。
  2. ab-ota(系统升级)与bg-dexopt(后台编译)使用的是[speed-profile],即只根据“热代码”的profile配置来编译。这也是N中混合编译的核心模式。
  3. 对于动态加载的代码,即forced-dexopt,它采用的是[speed]模式,即最大限度的编译机器码,它的表现与之前的AOT编译一致。

总的来说,程序使用loaddex动态加载的代码是无法享受混合编译带来的好处,我们应当尽量采用ClassN.dex方式来符合Google的规范。这不仅在ota还是混合编译上,都会带来很大的提升。

Profile-guided compilation

JIT WORK FLOW

dex2oat编译

首先我们来看系统在什么时候会对各个应用做JIT/AOT编译呢?手机在充电+空闲等多个条件下,通过BackgroundDexOptService.java中的JobSchedule下触发编译优化。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 js.schedule(new JobInfo.Builder(JOB_IDLE_OPTIMIZE, sDexoptServiceName)
                    .setRequiresDeviceIdle(true)
                    .setRequiresCharging(true)
                    .setPeriodic(TimeUnit.DAYS.toMillis(1))
                    .build());

dex2oat编译参数

对于[speed-profile]模式,dex2oat编译命令的核心参数如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dex2oat --dex-file=./base.apk --oat-file=./base.odex --compiler-filter=speed-profile --app-image-file=./base.art
 --profile-file=./primary.prof ...

其流程:若dex2oat参数中有输入profile文件,会读取profile中的数据。与以往不同的是,这里不仅会根据profile文件来生成base.odex文件,同时还会生成称为app_image的base.art文件。

与boot.art类似,base.art文件主要为了加快应用的对“热代码”的加载与缓存。在apk启动时系统加载应用的oat文件以及可能存在的app image文件,app image的作用是记录已经编译好的“热代码”,并且在启动时一次性把它们加载到缓存。预先加载代替用时查找以提升应用的性能。

JIT 参数

  • dalvik.vm.usejit - Whether or not the JIT is enabled.
  • dalvik.vm.jitinitialsize (default 64K) - The initial capacity of the code cache. The code cache will regularly GC and increase if needed. It is possible to view the size of the code cache for your app with: $ adb shell dumpsys meminfo -d <pid>
  • dalvik.vm.jitmaxsize (default 64M) - The maximum capacity of the code cache.
  • dalvik.vm.jitthreshold <integer> (default 10000) - This is the threshold that the "hotness" counter of a method needs to pass in order for the method to be JIT compiled. The "hotness" counter is a metric internal to the runtime. It includes the number of calls, backward branches & other factors.
  • dalvik.vm.usejitprofiles <true|false> - Whether or not JIT profiles are enabled; this may be used even if usejit is false.
  • dalvik.vm.jitprithreadweight <integer> (default todalvik.vm.jitthreshold / 20) - The weight of the JIT "samples" (see jitthreshold) for the application UI thread. Use to speed up compilation of methods that directly affect users experience when interacting with the app.
  • dalvik.vm.jittransitionweight <integer>(dalvik.vm.jitthreshold / 10) - The weight of the method invocation that transitions between compile code and interpreter. This helps make sure the methods involved are compiled to minimize transitions (which are expensive).
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-08-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android性能优化 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android N 混合编译与对热补丁影响解析
大约在六月底,Tinker在微信全量上线了一个补丁版本,随即华为反馈在Android N上微信无法启动。冷汗冒一地,Android N又搞了什么东东?为什么与instant run保持一致的补丁方式也
张绍文
2017/07/18
3.6K0
Android N 混合编译与对热补丁影响解析
Android N混合编译与对热补丁影响解析
首先非常抱歉Tinker没有按期内测,这主要因为开源的代码需要通过公司内部审核与评测,这项工作大约还需要一个月左右。当前Tinker已经在公司内部开源,我们会努力让它以更完善的姿态与大家见面。 大约在六月底,Tinker在微信全量上线了一个补丁版本,随即华为反馈在Android N上微信无法启动。冷汗冒一地,Android N又搞了什么东东?为什么与instant run保持一致的补丁方式也跪了?talk is cheap,show me the code。趁着台风妮妲肆虐广东,终于有时间总结一把。在此非常
微信终端开发团队
2018/01/29
3.4K0
Android N混合编译与对热补丁影响解析
Android 8.0 dexopt执行时机
在Android 8.0中 , 一共有5中编译时机 (或者说原因) , 而dexopt会根据这几个场景进行不同的编译过程 , 而对应的过程所使用的编译方法则是通过在SystemProperty中提前预置 , 在使用时从SystemProperty中读取来定义. :
None_Ling
2020/11/26
2.1K2
Android 8.0 dexopt执行时机
Android各版本虚拟机的Dexopt区别
从Android 2.1版本到现在的Android 11 , 中间虚拟机变化过三次 :
None_Ling
2020/12/02
3.4K0
Android各版本虚拟机的Dexopt区别
一次Art Hook失败问题的跟进
最近在使用一款Art Hook框架对应用进行Hook的时候发现,函数Hook之后却总是没有被触发,于是怀疑是被dex2oat做了Inline处理。
drunkdream
2020/01/02
1.1K0
从JVM到Dalivk再到ART(class,dex,odex,vdex,ELF)
现在市面上的 Android 手机大部分都是运行的是ART虚拟机了。还记得自己一部 Android手机(HuaweiG520),Android4.1 系统。那时候还是没有 ART虚拟机 的。作为Android开发者,我们应该对 Android 的发展历史有些了解为什么 Android 会经历这么多的变化。Android 是先有 JVM 然后是 Dalvik ,接着是现在的 ART虚拟机 。那么他们之间有什么关系呢?
静默加载
2020/05/29
2.2K0
Android虚拟机的JIT编译器
最近参加了华为方舟的Workshop,从编译到Runtime都有了一些体会,并且对于虚拟机的运行也有了一些了解。
None_Ling
2019/06/14
1.5K0
Android虚拟机的JIT编译器
Dalvik,ART与ODEX简析
如果你有这样的问题: 1.Dalvik和ART的区别 2.DEX在Dalvik转化为ODEX和ART中转化为ODEX的过程有上面区别 3.multidex在dalvik上起作用,ART上使用的也是multidex么(如果不是的话在application中写入multidex.install会对apk启动造成影响么)
Anymarvel
2018/10/22
1.6K0
Dalvik,ART与ODEX简析
ART 在 Android 安全攻防中的应用
在日常的 Android 应用安全分析中,经常会遇到一些对抗,比如目标应用加壳、混淆、加固,需要进行脱壳还原;又或者会有针对常用注入工具的检测,比如 frida、Xposed 等,这时候也会想知道这些工具的核心原理以及是否自己可以实现。
evilpan
2023/02/12
1.3K0
ART 在 Android 安全攻防中的应用
ART dex2oat Compiler –Quick 和Optimizing
我们知道,在Android的最初的几个版本,Android的app 运行在Dalvik中,完全是解释性执行.在Android2.2中,Google把JVM中常用的技术JIT带进了Dalvik,并且增加了多线程的处理能力.在L 中,正式推出ART.
用户9732312
2022/05/13
5070
ART dex2oat Compiler –Quick 和Optimizing
热修复Class流派和Dex流派实现原理
基本原理:加载类的时候是找element,每个element对于一个dex。我要把我修复的那个类单独放到dex插入dexlist前面,在你做类加载从前往后找优先从你的dex加载加载的就是你修复后的class.这就是
小柔
2022/12/07
5740
热修复Class流派和Dex流派实现原理
【Android开发丨主题周】ART 的上位与 JIT 的回归
Android应用程序主要是通过Java语言开发的(当然,也可以结合NDK通过C/C++开发。另外,从Android N开始,Kotlin已经成为Android官方开发语言,但实际上Kotlin的编译产物仍然是在虚拟机上运行的)。Java语言的编译产物是不能直接在设备上运行的,而必须借助于虚拟机来执行。
博文视点Broadview
2020/06/12
6300
【Android开发丨主题周】ART 的上位与 JIT 的回归
【Android 安装包优化】APK 打包流程 ( 文件结构 | 打包流程 | 安装流程 | 安卓虚拟机 )
将打包好的 APK 文件安装到 Android 手机中 , 就是可运行的应用程序 ;
韩曙亮
2023/03/29
1.4K0
【Android 安装包优化】APK 打包流程 ( 文件结构 | 打包流程 | 安装流程 | 安卓虚拟机 )
Android系统启动——4 zyogte进程 (C篇)
我们大家都是知道"一鼎三足"和"三角形的稳定性",那么支撑Android系统的三个"足"是什么?即init进程、SystemServer进程和Zygote进程。本篇文章我们就好好来研究下Zygote进程
隔壁老李头
2018/08/30
2.8K0
Android系统启动——4 zyogte进程 (C篇)
dex优化对Arouter查找路径的影响
1、通过aapt打包资源文件res,对应生成R.java、resources.arsc和res文件(二进制&非二进制保持原来的代码)
2020labs小助手
2021/06/04
9200
【Android 逆向】修改 Android 系统文件 ( default.prop 配置信息 | 修改 default.prop 配置信息文件 )
使用 cat default.prop 命令 , 查看 default.prop -> system/etc/prop.default 文件信息 ; 这是 Android 系统的默认属性 ;
韩曙亮
2023/03/29
1.7K1
【Android 逆向】修改 Android 系统文件 ( default.prop 配置信息 | 修改 default.prop 配置信息文件 )
Tinker原理
Tinker采用的是下发差分包,然后在手机端合成全量的dex文件进行加载。而在build.gradle配置中的tinkerPatch
老马的编程之旅
2022/06/22
6390
Tinker原理
我为Dexposed续一秒——论ART上运行时 Method AOP实现
两年前阿里开源了Dexposed 项目,它能够在Dalvik上无侵入地实现运行时方法拦截,正如其介绍「enable ‘god’ mode for single android application」所言,能在非root情况下掌控自己进程空间内的任意Java方法调用,给我们带来了很大的想象空间。比如能实现运行时AOP,在线热修复,做性能分析工具(拦截线程、IO等资源的创建和销毁)等等。然而,随着ART取代Dalvik成为Android的运行时,一切都似乎戛然而止。
weishu
2018/09/05
1.8K0
我为Dexposed续一秒——论ART上运行时 Method AOP实现
Android系统启动之zyogte进程
ygote进程在android系统中有着及其中要的位置. 可以说android系统中的进程都是有zygote孵化出来的, 所有应用进程都是zygote的子进程. 参考图片:
李小白是一只喵
2020/04/23
1.2K0
Android系统启动之zyogte进程
Dalvik虚拟机和ART
http://blog.csdn.net/watermusicyes/article/details/50526814
tea9
2022/07/16
5000
相关推荐
Android N 混合编译与对热补丁影响解析
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文