详解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,谷歌在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是如何工作的(1)从4.4到7.0,ART一开始只使用AOT编译。App安装时,所有代码都编译存储在本地,打开App直接运行。这样做的好处是app运行速度更快,但缺点也很明显,App安装时间明显变长,而且占用存储空间大(2)7.0AndroidN之后,ART发生了变化,并且重新引入了JIT编译,并结合了AOT/JIT混合编译。主要机制如下:不进行安装。编译,前几次运行只通过解释器运行,JIT同时编译热点代码,并将这些代码的相关信息记录在一个配置文件中。当设备空闲和充电时,编译守护进程读取配置文件,对热点代码进行AOT编译,写入app对应的odex文件中。再次启动应用后,先使用AOT编译代码,否则使用解释器+JIT编译,重复这个过程。对于一些庞大的应用,比如某些宝,有些功能可能你一辈子都用不到。按照上面的策略,这部分代码不会被编译保存,从而减少占用的存储空间。此外,在系统升级时,也避免了对现有所有应用程序进行全量编译所带来的时间和空间消耗。(3)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采用JIT。ART支持64位CPU,兼容32位CPU,而Dalvik只支持32位CPU。ART改进并优化了垃圾收集器以提高吞吐量。一句话概括核心内容:app在安装时不编译代码,只校验合法性,运行时通过解释器执行,将频繁运行的代码编译到内存缓存中记录在本地配置文件,后台线程编译配置文件记录的方法保存在.odex文件中,再次运行app时,会先读取.odex文件中的编译代码,然后重复这个过程。
