Dalvik、ART、JVM
Dalvik虚拟机
dex文件
Java虚拟机运行的是java字节码,即class文件,而Dalvik虚拟机执行的是专有的dex格式字节码,dex文件是由一个或多个class文件打包而成。dex体积更小,class文件都有一个常量池,而dex文件只有一个常量池,多个class文件如果有重复的字符串,在dex文件里只有一份。
dex文件生成:
- javac 把.java文件编译成.class文件
- dx工具:在sdk/build-tools/中的dx工具,执行命令dx --dex --output="文件名.dex" [class文件地址]
- 在jdk 1.8 可能会出现错误,提示不支持当前版本,所以编译时要强制用低版本的jdk编译,如javac -source 1.7 -target 1.7 [java文件]
odex文件
- odex是Optimized dex 的简写,即优化后的dex文件,主要是为了提高Dalvik虚拟机的运行速度。
- odex文件时dex文件具体在某个系统上的优化。odex文件优化依赖系统上的几个核心模块,一般是/system/framwork/下的jar包,尤其是core.jar。odex的优化及时把本来需要在执行过程中做的类校验、调用其他类函数时的解析等工作提前处理。
Dalvik虚拟机的启动
在Android系统中,应用程序进程都是由Zygote进程孵化出来的,而Zygote进程是由Init进程启动的。Zygote进程在启动时会创建一个Dalvik虚拟机实例,每当它孵化一个新的应用程序进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面去,从而使得每一个应用程序进程都有一个独立的Dalvik虚拟机实例。Zygote是虚拟机实例的孵化器。AndroidRuntime.cpp中ZygoteInit.main()的执行会完成一个分裂,分裂出来的子进程继续初始化Java层的架构,这个分裂出来的进程就是system_server。每当系统要求执行一个Android应用程序,Zygote就会fork出一个子进程来执行该应用程序。system_server是应用与Zygote之间交流的桥梁,通过socket进行通信。Android系统启动加载完内核后,第一个执行的是init进程,init进程首先要做的是设备的初始化工作,然后读取inic.rc文件并启动系统中的重要外部程序 Zygote。Zygote进程是Android所有进程的孵化器进程,它启动后会首先初始化Dalvik虚拟机,然后启动system_server并进入Zygote模式,通过socket等候命令。当执行一个Android应用程序时,system_server进程通过Binder IPC方式发送命令给Zygote,Zygote收到命令后通过fork自身创建一个Dalvik虚拟机的实例来执行应用程序的入口函数,这样一个程序就启动完成了。
Dalvik和Jvm之间的区别
- Dalvik和Jvm最大的区别是Dalvik基于寄存器结构,而Jvm基于栈结构。一般来说基于寄存器结构的运行速度更快,但代码长度会边长,这也是现在很多cpu采用的结构。
- Dalvik虚拟机运行dex格式的字节码,而Jvm虚拟机运行class格式的字节码。 Dalvik虚拟机所占空间小,且可执行文件体积小。
- 每Dalvik负责进程隔离和线程管理,每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行。
Dalvik和ART的区别
Android Runtime,在android 5.0以后及后续版本取代Dalvik。
-
JIT最早在Android 2.2系统中引进到Dalvik虚拟机中,在应用程序启动时,JIT通过进行连续的性能分析来优化程序代码的执行,在程序运行的过程中,Dalvik虚拟机在不断的进行将字节码编译成机器码的工作。 与Dalvik虚拟机不同的是,ART引入了AOT这种预编译技术,在应用程序安装的过程中,ART就已经将所有的字节码重新编译成了机器码。应用程序运行过程中无需进行实时的编译工作,只需要进行直接调用。因此,ART极大的提高了应用程序的运行效率,同时也减少了手机的电量消耗,提高了移动设备的续航能力,在垃圾回收等机制上也有了较大的提升。 为了保证向下兼容,ART使用了相同的Dalvik字节码文件(dex),即在应用程序目录下保留了dex文件供旧程序调用然而.odex文件则替换成了可执行与可链接格式(ELF)可执行文件。一旦一个程序被ART的dex2oat命令编译,那么这个程序将会指通过ELF可执行文件来运行。因此,相对于Dalvik虚拟机模式,ART模式下Android应用程序的安装需要消耗更多的时间,同时也会占用更大的储存空间(指内部储存,用于储存编译后的代码),但节省了很多Dalvik虚拟机用于实时编译的时间。
-
核心库:Dalvik核心库libdvm.so,Art核心库libart.so
-
Art的核心是OAT文件。OAT文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容。