在本文中,我们将讨论Android运行时。特别是,我将尝试简要扼要地概述ART和Dalvik的不同之处,以及随着时间的推移Android开发工具的改进。该主题显然不是新话题,但我希望它对那些刚刚开始研究它的人派上用场。谁在乎-欢迎来到猫。
虚拟机
首先,让我们看看JVM与DVM的不同之处。
Java虚拟机是一个能够执行Java字节码的虚拟机,而与底层平台无关。它基于“编写一次,随处运行”的原则。Java字节码可以在任何支持JVM的机器上运行。
Java编译器将.java文件转换为类文件(字节码)。字节码被传递到JVM,JVM将其编译为机器码以直接在CPU上执行。
JVM功能:
- 它具有堆栈体系结构:堆栈用作放置和存储方法的数据结构。它适用于LIFO或“后进先出”或“后进先出”方案。
- 只能运行类文件。
- 使用JIT编译器。
Dalvik虚拟机(DVM)是由Dan Bornstein等人开发和编写的Java虚拟机,是Android移动平台的一部分。
我们可以说Dalvik是执行Android操作系统组件和自定义应用程序的环境。每个进程都在其自己的隔离地址空间中运行。当用户启动应用程序(或操作系统启动其组件之一)时,Dalvik虚拟机核心(Zygote Dalvik VM)在共享内存中创建一个单独的受保护进程,在其中,VM被直接部署为启动应用程序的环境。换句话说,从内部看,Android看起来像一组Dalvik虚拟机,每个虚拟机都运行一个应用程序。
DVM的功能:
- 使用基于寄存器的体系结构:放置方法的数据结构基于处理器寄存器。由于没有POP和PUSH操作,所以注册虚拟机中的指令执行速度要快于堆叠虚拟机中的类似指令。
- 执行本机格式字节码:Android dexer(我们将在下面讨论)将类文件转换为.dex格式,并针对在Dalvik VM上执行进行了优化。与类文件不同,dex文件一次包含多个类。
您可以在此处阅读有关DVM架构的更多信息。
Android Dexer
Android开发人员知道,为Android Runtime将Java字节码转换为.dex字节码的过程是创建APK的关键步骤。 dex编译器在日常应用程序开发中大多是在后台运行,但是它直接影响应用程序的构建时间,.dex文件大小和运行时性能。
如前所述,dex文件本身一次包含多个类。跨多个类文件使用的重复行和其他常量仅是为了节省空间。 Java字节码也被转换为DVM使用的备用指令集。未压缩的dex文件通常比从相同的.class文件获得的压缩Java归档文件(JAR)小百分之几。
最初,使用内置的DX编译器将类文件转换为dex文件。但是从Android Studio 3.1开始,D8成为默认的编译器。与DX编译器相比,D8编译速度更快,输出的dex文件更小,同时在运行时提供了更好的应用程序性能。使用开源ProGuard实用程序可以最小化以这种方式获得的dex字节码。结果,我们得到了相同的dex文件,但是较小。然后,此dex文件用于构建apk,最后部署到Android设备。
但是在2018年的D8之后是R8,实际上是相同的D8,只是添加了内容。
当使用Android Studio 3.4和Android Gradle 3.4.0或更高版本的插件时,Proguard不再在编译时用于优化代码。相反,该插件默认情况下可与R8一起使用,R8本身可进行代码缩减,优化和混淆。尽管R8仅提供Proguard提供的功能的子集,但它允许您一次将Java字节码转换为dex字节码,从而进一步减少了构建时间。
R8和代码减少
通常,应用程序使用Jetpack,Gson,Google Play服务等第三方库。当我们使用这些库之一时,通常应用程序仅使用每个库的一小部分。在不缩减代码的情况下,所有库代码都存储在您的应用程序中。
开发人员可能会使用冗长的代码来提高应用程序的可读性和可维护性。例如,有意义的变量名和设计模式可用于帮助其他人更轻松地理解代码。但是模板往往导致不必要的代码。
这就是R8抢救的地方。它允许您显着减小应用程序的大小,甚至可以优化应用程序实际使用的代码的大小。
例如,下面是在Android Dev Summit '19上展示的使用R8缩小您的应用程序报告中的数字:
这就是R8在beta版本发布阶段的有效性比较(摘自Android开发者博客):
更多详细信息在办公室文件和报告中。
Android中的ART vs DVM
DVM是专为移动设备设计的,被用作虚拟
机,以运行高达Android 4.4 Kitkat的android应用程序。
从此版本开始,ART作为运行时引入,在Android 5.0(Lollipop)中,ART完全替代了Dalvik。
ART和DVM之间的主要明显区别是ART使用AOT编译,而DVM使用JIT编译。不久前,ART开始使用AOT和JIT的混合体。让我们仔细看看。
DVM
- 使用JIT编译:每当应用程序启动时,
- 运行该应用程序所需的部分代码已编译。其余代码是动态编译的。这减慢了应用程序的启动和运行速度,但减少了安装时间。
- , .
- , DVM, , , ART.
- , CPU.
- Dalvik “” 4.4.
ART
- AOT , . , .
- , .
- AOT , DVM.
- , - .
- 改进了垃圾回收或垃圾回收。使用Dalvik时,垃圾收集器必须进行2次堆传递,从而导致UX效果不佳。对于ART,没有这种情况:它只清理一次堆以合并内存。
还有一张Dalvik vs ART的小图:
JIT + AOT艺术
自Android 7起的Android运行时(ART)包括具有代码配置文件的JIT编译器。 JIT编译器是AOT编译器的补充,并提高了运行时性能,节省了磁盘空间并加快了应用程序和系统更新的速度。
发生这种情况的方式如下:
而不是在安装阶段运行每个应用程序的AOT编译,而是使用JIT编译器在虚拟机的控制下运行该应用程序(与Android <5.0几乎相同),但是跟踪哪个应用程序代码的各个部分最常执行。然后,此信息将用于AOT编译这些代码段。仅当智能手机正在充电时处于非活动状态时,才执行后一种操作。
简而言之,现在两种完全不同的方法可以协同工作,从而具有其优势:
- 更有效的编译-实时运行应用程序时,与进行静态分析相比,编译器有机会了解更多有关其工作的信息,因此,针对每种情况采用了更合适的优化方法;
- 保留RAM和永久存储器-字节码比机器代码更紧凑,并且如果仅对应用程序的某些部分执行AOT编译并且不对用户不使用的应用程序进行编译,则可以显着节省NAND存储器空间;
- 系统更新后,安装和首次启动速度大大提高-无需AOT编译,没有延迟。
在此处阅读有关JIT编译器在ART中的实现的更多信息。
结论
在本文中,我试图看一下Dalvik和ART之间的主要区别,并且通常看一下Android如何随着时间的推移改进其开发工具。
ART仍在开发中,将添加新功能以改善用户和开发人员的体验。
如果有帮助,请在评论中告诉我。