当前位置: 首页 > 科技观察

Android虚拟机Dalvik与ART

时间:2023-03-18 01:13:50 科技观察

详解Android应用程序是用Java/Kotlin编写的。Android虚拟机不使用JVM字节码,而是通过Class文件的DX编译器(现已被D8取代)编译出程序dex文件。然后由虚拟机执行;在底层看来,无论是java还是kolin,最终都是机器码跑的;废话不多说,下面先简单介绍一下Dalvik1.Dalvik虚拟机介绍Dalvik是Google为Android平台设计的虚拟机。机器。Dalvik虚拟机是谷歌等厂商联合开发的Android移动设备平台的核心组件之一。它可以支持运行已转换为.dex(即DalvikExecutable)格式的Java应用程序。.dex格式是专门为Dalvik设计的压缩格式,适用于内存和处理器速度有限的系统。Dalvik经过优化,允许多个虚拟机实例在有限的内存中同时运行,每个Dalvik应用程序都作为一个独立的Linux进程执行。一个独立的进程可以防止虚拟机崩溃时所有程序都关闭;2.DalvikAndroid1.0的诞生与消亡史,使用Dalvik作为Android虚拟机的运行环境;Android2.2,Google在Andriod虚拟机中加入了JIT编译器(Just-In-TimeCompiler);Android4.4,谷歌带来了全新的虚拟机运行环境ART,此时ART与Dalvik共存,用户可以在两者之间进行选择;Android5.0,ART完全取代了Dalvik,成为了Android虚拟机的运行环境,至此Dalvik退出了历史舞台;3.Dalvik特性Dalvik虚拟机运行Dalvik字节码,由Java字节码转换打包成dex文件。JVM运行类文件或jar文件;加载速度快,与Jar文件相比,dex会整合其中包含的所有信息,减少冗余信息。这样减少了I/O操作,提高了类的查找速度;Dalvik虚拟机基于寄存器,而JVM基于栈(操作数栈)。基于寄存器的执行效率虽然好,但可移植性差,难以跨平台;Dalvik虚拟机允许多个进程在有限的内存中同时运行,每个应用程序运行在一个Dalvik虚拟机实例中,拥有独立的进程空间;Dalvik虚拟机有共享机制,不同的应用在运行时可以共享同一个类,效率更高;二、ART虚拟机1、ART概念介绍ART虚拟机在Android5.0开始取代Dalvik虚拟机。它处理应用程序执行的方式与Dalvik虚拟机不同。它不使用JIT而是使用AOT(Ahead-Of-Time),也就是提前编译技术。并且垃圾收集器也得到了改进和优化;ART虚拟机从Android4.4开始作为选项引入,Android5.0后Dalvik被替换,Android7.0和8.0分别做了一系列的改动2、基本概念和名词。.dex文件:编译app所有java源码后,生成很多class文件,由DX/D8编译成一个/多个(multiDex)dex文件,由Android虚拟机编译执行;.odex文件:dex文件经过验证和优化,art下的odex文件包含了AOT编译后的代码和dex的完整内容,但在Android8.0之后,odex中的dex内容被移到了.vdex文件中;.art文件:根据art下的配置生成odex文件时,同时生成.art文件。主要目的是提高odex在运行时加载热点代码的速度。它包含了类信息和odex中热点方法的索引。运行app时,会先根据这个文件加载odex中已有的代码。编译代码解释器(Interpreter):用于在程序运行时逐行解释代码,翻译成相应平台的机器码执行;JIT编译(JustInTime):引入是因为解释器模式运行速度太慢,针对频繁运行的热点代码(判断标准一般是一定时间内执行次数达到一定阈值)进行实时编译(ART下方法的粒度),JIT编译后的代码缓存在内存中,以备下次执行。在方法粒度(ArtMethod)上进行编译,JIT编译器可以生成更高效的代码,并且比解释器运行得更快;AOT编译(Ahead-Of-Time):应用安装时将所有代码全编译成本地机器码,运行时直接执行机器码;3.ART是如何工作的①4.4~7.0ART一开始只使用AOT编译。安装应用程序时,所有代码都编译并存储在本地。打开App,直接运行。速度更快,缺点也很明显。App安装时间明显变长,占用存储空间大。7.0AndroidN之后,改变了ART,重新引入了JIT编译。结合AOT/JIT混合编译,主要机制如下:安装时不进行编译,前几次运行只通过解释器解释运行。同时对热点代码进行JIT编译,并将这些代码的相关信息记录在配置文件中。当设备空闲和充电时,编译守护进程读取配置文件,对热点代码进行AOT编译写入app对应的odex文件中。再次启动应用后,先使用AOT编译后的代码,否则使用解释器+JIT编译,重复这个过程。对于一些庞大的应用,比如某宝,有些功能你可能一辈子都不会用到。按照上面的策略,这部分代码不会被编译保存,从而减少占用的存储空间。此外,在系统升级时,也避免了对现有所有应用程序进行全量编译所带来的时间和空间消耗。③8.0Android8.0引入了.vdex文件,其中包含了APK未压缩的DEX代码,以及一些用来加速验证的元数据;4、ART垃圾收集器优化只有一次GC暂停(Dalvik需要两次)并发复制,可以减少后台内存使用,片段GC暂停时间不受堆大小影响在清理最近分配的短生命期对象的特殊情况下,收集器的总GC时间更短,优化了垃圾收集的效率,可以更及时地进行并行垃圾收集,这使得GC_FOR_ALLOC事件在典型用例中极为罕见5.ART时间轴Android4.4,ART和Dalvik并存,用户可以在两者之间进行选择。Android5.0正式取代Dalvik虚拟机成为Android虚拟机的运行环境,Dalvik退出了历史舞台,AOT取代了JIT。Android7.0,JIT回归,采用JIT和AOP混合编译方式。ART持续更新优化6、DalvikVM和ARTVM有什么区别?ART前期使用AOT技术,后期使用AOT+JIT混合,而Dalvik使用JITART支持64位CPU并兼容32位CPU,而Dalvik只支持32位CPU。收集器已得到改进和优化以提高吞吐量。核心内容用一句话概括:安装app时,不编译代码,只校验有效性。运行时,通过解释器执行,将频繁运行的代码编译保存在内存缓存中并记录下来。在本地配置文件中,后台线程编译配置文件记录方法,保存在.odex文件中。再次运行App时,先读取.odex文件中的编译代码,然后重复上述过程。