摘抄自<<Android 进阶解密>>一书
DVM
运行时堆使用了标记清除算法进行GC
的
jvm
基于栈则需要从栈中读写数据,所需的指令会更多,这样导致运行速度慢,这对于性能有限的移动设备不合适。DVM
是基于寄存器的,它没有基于栈的虚拟机在复制数据时而使用大量的出入栈指令,同时指令更加紧凑,简单,基于寄存器的指令要大,但是指令数量减少,总的代码数并不会增加多少
Java
类被编译成一个或多个.class
文件,并打包成jar
文件,然后JVM
会通过相应的.class
文件与jar
文件获取相应的字节码。执行顺序.java
文件->.class
文件->.jar
文件,而DVM
会用dx
工具将所有的class
文件转换成.dex
文件,然后它会从该.dex
文件中读取指令与数据。执行顺序.java
文件->.class
文件->.dex
文件
.jar
文件中包含多个.class
文件,每个.class
文件又包含该类的常量池、类信息属性等。当JVM
加载该类的jar
文件时候,会加载里面所有的.class
文件。加载很慢。而.apk
文件中只包含一个.dex
文件,这个.dex
文件将所有的.class
文件整合了,这样加载就加快了速度。dex
工具会去除冗余的信息,并把所有的.class
文件整合到.dex
文件中,减少了I/O
操作,加快了类的加载速度。
在Android
中,每个应用都运行在一个DVM
实例中,每个该实例都运行在一个独立的进程空间中,可以防止虚拟机崩溃时候所有程序关闭
Zygote
是一个DVM
进程,同时用来创建于初始化DVM
实例。每当系统需要创建一个应用程序时,Zygote
就会fork
自身,快速创建和初始化一个DVM
实例,用于应用程序的运行。对于一些只读的系统库,所有DVM
实例都会和Zygote
共享一块内存区域,节省内存开销
它拥有预加载共享机制,不同应用之间在运行时可以共享相同的类。而JVM没有共享机制,不同程序打包后都是彼此独立的
JVM
使用了JIT
编译器,而DVM
是在Android2.2
开始使用的,它对多次运行代码进行编译,生成相当精简的本地机器码,这样下载执行到相同的罗技时候,直接编译机器码,不是每次都需要编译。
ART
虚拟机是Android4.4
发布的,从Android5.0
开始默认采用ART
DVM
每次运行时,都需要编译成机器码,运行效率低下,而ART
中,系统在安装应用程序时会进行一个AOT
(预编译),将字节码编译成机器码并存储在本地,这样运行效率大大提升,但是设备耗电增加。采用AOT
编译会造成程序安装时间变长与存储空间增加在Android7.0 ART
加入了编译器JIT
,作为AOT
的补充,在应用程序安装时并不会将字节码全部编译成机器码,而是在运行中将多次运行的代码编译成机器码,从而缩短时间与节省空间
DVM
为32位CPU
设计,而ART
同时支持32与64位ART
对垃圾回收进行改进,将GC
暂停由两次减少为1次ART
运行时候堆空间划分与DVM
不同DVM
与ART
都是在Zygote
进程中诞生的,这样Zygote
就持有它们的实例,此后Zygote
通过fork
自身创建应用程序进程时候,应用程序进程也得到了DVM
与ART
实例,这样就无需每次启动应用程序进程都要创建,加快应用程序进程的启动速度。