一、概念
Dalvik是Google公司设计的用于Android平台的Java虚拟机,它是Android平台的重要组成部分,运行于Android的运行时库层。Dalvik支持dex格式(Dalvik Executable)的Java应用程序的运行。dex格式是专门为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。
Dalvik作为面向Linux、为嵌入式操作系统设计的虚拟机,主要负责完成对象生命周期管理、堆栈管理、线程管理、安全和异常管理以及垃圾回收等功能。Dalvik早期并没有JIT编译器,直到Android 2.2才加入了对JIT编译器的技术支持。另外,Dalvik是基于寄存器指令集架构的虚拟机,而不是基于栈指令集架构的虚拟机。
二、Dalvik字节码
Java虚拟机运行的是Java字节码,Java代码经过编译生成Java字节码保存在class文件中,Java虚拟机通过解码class文件中的内容来运行程序。而Dalvik虚拟机运行的是Dalvik字节码,所有的Dalvik字节码由Java字节码转换而来,并被打包到一个dex(Dalvik Executable)可执行文件中,Dalvik虚拟机通过解释dex文件来执行字节码。
流程如下:
![](https://img.haomeiwen.com/i8897049/cbb77955396f030f.jpg)
Android SDK中有一个叫dx的工具负责将Java字节码转换为Dalvik字节码。dx工具对Java类文件重新排列,消除在类文件中出现的所有冗余信息。一般情况下,Java类文件中包含多个不同的方法签名,如果其他的类文件引用该类文件中的方法,方法签名也会被复制到其他的类文件中,也就是说,多个不同的类文件会同时包含相同的方法签名,同样地,大量的字符串常量在多个类文件中也被重复使用,这些冗余信息会直接增加文件的体积,同时也会严重影响虚拟机解析文件的效率。消除其中的冗余信息,重新组合形成一个常量池,所有的类文件共享同一个常量池,从而减小了文件的体积。
![](https://img.haomeiwen.com/i8897049/52c1d190d5a51808.jpg)
![](https://img.haomeiwen.com/i8897049/e692b4d8e756dd5c.jpg)
在应用程序安装时,Dalvik会将dex文件优化成odex文件。
三、解释器与JIT即时编译器
Dalvik虚拟机同其他大多数Java虚拟机一样,都使用了JIT即时编译器,Dalvik虚拟机将dex或odex中并排的Dalvik字节码在运行时编译成本地机器码去执行。JIT即时编译器的引入使得Dalvik提升了3~6倍的性能。
四、指令集架构
Java虚拟机与Dalvik虚拟机架构不同,这也是两者最大的区别。Java虚拟机基于栈架构,程序在运行时虚拟机需要频繁的从栈上读取或写入数据,这个过程需要更多的指令分派与内存访问次数,会耗费不少CPU时间,对于像手机这样的资源有限的设备来说,这是相当大的一笔开销。而Dalvik虚拟机基于寄存器架构,数据的访问通过寄存器间直接传递,这样的访问方式比基于栈方式要快很多。
五、垃圾收集器
Dalvik上垃圾回收触发时机:
- 堆中无法再创建对象的时候。
- 堆中的内存使用率超过阈值的时候。
- 程序通过Runtime.gc()主动GC的时候。
- 在OOM发生之前的时候。
Dalvik在进行垃圾回收时会挂起用户线程,造成应用程序卡顿,同时使用标记整理算法会导致内存碎片化,虚拟机还需要对碎片进行整理。
Dalvik的内存管理是基于传统的dlmalloc内存分配器实现的,这个内存分配器在Linux上很常用。Dalvik的内存整理是直接利用了dlmalloc中的mspace_bulk_free函数进行处理的。但是dlmalloc没有为多线程环境做过优化,分配内存时使用了全局的内存锁,这就很容易造成性能不佳。
网友评论