深入理解Android-Runtime

上图是Android全体的架构,Android Runtime之于Android而言相当于心脏之于人体,是Android程序加载和运转的环境。这篇文章首要针对Android Runtime部分进行翻开,探讨Android Runtime的发展以及现在现状,并介绍运用Profile-Guided Optimization(PGO)技能对运用发动速度进行优化的可行性。转载请注明来历「申国骏」

App运转时演进

JVM

Android原生代码运用Java或许Kotlin编写,这些代码会通过javac或许kotlinc编译成.class文件,在Android之前,这些.class文件会被输入到JVM中履行。JVM能够简单分为三个子体系,分别是Class Loader、Runtime Data Area以及Execution Engine。其中Class Loader首要担任加载类、校验字节码、符号引证链接及对静态变量和静态办法分配内存并初始化。Runtime Data担任存储数据,分为办法区、堆区、栈区、程序计数器以及本地办法栈。Execution Engine担任二进制代码的履行以及垃圾回收。

深入理解Android-Runtime

Execution Engine中,会选用Interpreter或许JIT履行。其中Interpreter表明在运转的进程中对二进制代码进行解说,每次履行相同的二进制代码都进行解说比较浪费资源,因而关于热区的二进制代码会进行JIT即时编译,对二进制代码编译成机器码,这样相同的二进制代码履行时,就不用再次进行解说。

深入理解Android-Runtime

DVM(Android 2.1/2.2)

JVM是stack-based的运转环境,在移动设备中对性能和存储空间要求较高,因而Android运用了register-based的Dalvik VM。从JVM转换到DVM咱们需求将.class文件转换为.dex文件,从.class转换到.dex的进程需求通过 desugar -> proguard -> dex compiler三个进程,这三个进程后来逐渐变成 proguard -> D8(Desugar) 直到演变到今天只需求一步R8(D8(Desugar))。

深入理解Android-Runtime

咱们首要重视Android中Runtime Engine与JVM的差异。在Android早期的版别里边,只存在Interpreter解说器,到了Android2.2版别将JIT引进,这个版别Dalvik与JVM的Runtime Engine差异不大。

深入理解Android-Runtime

ART-AOT(Android 4.4/5.0)

为了加快运用的发动速度和体会,到了Android4.4,Google供给了一个新的运转时环境ART(Android Runtime),到了Android5.0,ART替换Dalvik成为唯一的运转时环境。

深入理解Android-Runtime

ART运转时环境中,选用了AOT(Ahead-of-time)编译方法,即在运用装置的时分就将.dex提前编译成机器码,通过AOT编译之后.dex文件会生成.oat文件。这样在运用发动履行的时分,由于不需求进行解说编译,大大加快了发动速度。

深入理解Android-Runtime

然而AOT带来了以下两个问题:

  1. 运用装置时间大幅增加,由于在装置的进程中一起需求编译成机器码,运用装置时间会比较长,特别在体系升级的时分,需求对一切运用进行从头编译,呈现了经典的升级等待噩梦。

深入理解Android-Runtime

  1. 运用占用过多的存储空间,由于一切运用都被编译成.oat机器码,运用所占的存储空间大大增加,使得原本并不富余的存储空间变得雪上加霜。

进一步思考对运用全量进行编译或许是没有必要的,由于用户或许只会用到一个运用的部分常用功用,而且全量编译之后更大的机器码加载会占用IO资源。

ART-PGO(Android 7.0)

从Android7.0开端,Google从头引进了JIT的编译方法,不再对运用进行全量编译,结合AOT、JIT、Interpreter三者的优势提出了PGO(Profile-guided optimization)的编译方法。

在运用履行的进程中,先运用Interpreter直接解说,当某些二进制代码被调用次数较多时,会生成一个Profile文件记载这些办法存储起来,当二进制代码被频频调用时,则直接进行JIT即时编译并缓存起来。

当运用处于闲暇(屏幕关闭且充电)的状况时,编译看护进程会依据Profile文件进行AOT编译。

当运用从头翻开时,进行过JIT和AOT编译的代码能够直接履行。

这样就能够在运用装置速度以及运用翻开速度之间取得平衡。

深入理解Android-Runtime

深入理解Android-Runtime

JIT 工作流程:

深入理解Android-Runtime

ART-Cloud Profile(Android 9.0)

不过这儿仍是有一个问题,便是当用户第一次装置运用的时分并没有进行任何的AOT优化,一般会通过用户屡次的运用才能使得发动速度得到优化。

深入理解Android-Runtime

考虑到一个运用一般会有一些用户经常运用履行的代码(例如发动部分以及用户常用功用)而且大多数时分会有先行版别用于搜集Profile数据,因而Google考虑将用户生成的Profile文件上传到Google Play中,并在运用装置时一起带上这个Profile文件,在装置的进程中,会依据这个Profile对运用进行部分的AOT编译。这样当用户装置完第一次翻开的时分,就能到达较快的发动速度。

深入理解Android-Runtime

深入理解Android-Runtime

Profile in cloude 需求体系运用市场支持,在国内市场运用Google Play的占比非常低,因而cloud profile的优化在国内简直是没有效果的,不过Profile的机制供给了一个能够做发动优化的思路。早在2019年,支付宝就在秒开技能的回应的里边提到过profile-based compile的技能,参阅:怎么看待今天头条自媒体发布谣言称「支付宝简直秒开是由于选用华为方舟编译器」?,这也是咱们一向研究Profile技能的原因。困扰着咱们的一向有两个问题,第一个问题是怎么生成Profile文件,第二个问题是怎么运用生成的Profile文件。关于第一个问题的处理相对仍是有思路的,由于app运转就会生成profile文件,因而咱们手动运转几回app就能在文件体系中搜集到这个文件,不过怎么以一种较为自动化的手段搜集仍然是个问题。第二个问题咱们知道Profile文件最终生成的位置,因而咱们能够把生成的文件放到相应的体系目录,不过大多数手机和运用都没有权限直接放置这个文件。因而Profile优化技能一向都没有落地,直到Baseline Proflie让咱们看到了希望。

Baseline Profile

Baseline Profile是一套生成和运用Profile文件的东西,在2022年一月份开端进入视野,随后在Google I/O 2022跟着Jetpack新变化得到广泛重视。其布景是Google Map加快了发版速度,Cloud Profle还没彻底搜集好就上新版,导致Cloud Proflie失效。还有一个布景是Jetpack Compose 不是体系代码,因而没有彻底编译成机器码,而且Jetpack Compose库比较大,因而在Profile生成之前运用了Jetpack Compose的运用发动会产生性能问题。最后Google为了处理这些问题,发明了搜集Profile的BaselineProfileRule Macrobenchmark以及运用Profile的ProfileInstaller。

运用Baseline Profile的机制能够在Android7及以上的手机上得到运用的发动加快,由于从上述知道Android7就现已开端有PGO(Profile-guided optimization)的编译方法。生成的Profile文件会打包到apk里边,而且会结合Google Play的Cloud Profile来引导AOT编译。虽然在国内基本上用不了Cloud Profile,不过Baseline Profile是能够独立于Google Play独自运用的。

深入理解Android-Runtime

在运用了Baseline Proflie之后,有道词典的发动速度从线上计算上看,冷发动时间有15%的提高。

这篇文章首要介绍了Android Runtime的演进以及关于运用发动的影响,下一篇文章我会具体介绍关于Profile&dex文件优化、Baseline Profile东西库原理,以及在实际操作上怎么运用的问题,敬请大家期待一下!

参阅

  • Android CPU, Compilers, D8 & R8

  • Implementing ART Just-In-Time (JIT) Compiler

  • Configuring ART

  • Improving app performance with ART optimizing profiles in the cloud

  • Understanding Android Runtime (ART) for faster apps (Google I/O’19)

  • What’s new in Android Runtime (Google I/O ’18)

  • Performance and memory improvements in Android Run Time (ART) (Google I/O ’17)

  • The Evolution of ART – Google I/O 2016

  • Google I/O 2014 – The ART runtime

  • Google I/O 2010 – A JIT Compiler for Android’s Dalvik VM

  • Android Runtime  –  How Dalvik and ART work?

  • Android Debug Bridge – Read ART profiles for apps

  • Deep dive into the ART runtime (Android Dev Summit ’18)

  • Deep dive into ART(Android Runtime) for dynamic binary analysis | SungHyoun Song | Nullcon 2021

  • Baseline Profiles

  • Google I/O 2022: What’s new in Jetpack

  • Improving App Performance with Baseline Profiles

  • Android 强推的 Baseline Profiles 国内能用吗?我找 Google 工程师求证了!