Android Dalvik虚拟机基础

Android Dalvik虚拟机(尽管现在被art取代,但不代表它一无是处,了解dalvik有助于理解art)

在Android 4.4之前,Dalvik一直是Android中默认的虚拟机,后面推出了ART运行环境机制,逐步完全取代了Dalvik。Dalvik 和art都可以支持已经转换为.dex格式的java应用程序的运行。

 

一、Dalvik VM,JVM的差异:

1)多数JVM都是基于堆栈的,而DalvikVM是基于寄存器的,通常基于栈的机器需要更多的指令,而基于寄存器的机器指令更大。基于stack的vm必须使用指令来载入stack上的数据,或使用指令来操纵数据,所以需要更多的指令。

 

 

尽管Dalvik虚拟机 运行的是java语言,但是它不是按照java虚拟机规范来实现的,所以两者并不兼容。

 

2)在java se程序中,java类会被编译成一个或多个字节码文件.class,然后打包到jar文件,而后jvm虚拟机会从相应的Class文件和jar文件中获取相应的字节码;

Android应用的java类在编译成Class文件后,会通过一个工具dx将所有的class文件转换成一个DEX文件,而后dalvik从中读取指令和数据。

 

3)Dalvik VM经过优化,允许在有限的内存中同时运行多个虚拟机实例,并且每一个Dalvik VM应用作为一个独立的Linux进程执行。

 

二、Dalvik VM的特征

DEX文件格式会把所有的Class文件内容整合到一个文件中,减少了整体的文件尺寸和IO操作,也提高了类的查找速度。原来每个类文件中的常量池,在dex文件中由一个常量池负责管理。

 

每个虚拟机实例都是一个独立的进程空间,zygote是一个虚拟机实例的孵化器,当系统需要执行一个android应用程序,zygote就会fork一个子进程来执行该应用程序。

这样做的优点:zygote进程是系统启动时创建的,他会完成虚拟机的初始化、库的加载、预制类库的加载和初始化等操作;当系统需要一个新的虚拟机实例,zygote通过复制自身,快速的提供了一个子系统;对于一些只读性的系统库来说,所有虚拟机实例都和zygote共享一块内存区域,节省了内存开销。

 

基于寄存器的dalvikVM虽然在硬件通用性上差一些,但是在代码的执行效率上更快,可以更有效的减少冗余指令的分发和减少内存的读写访问。

 

三、Dalvik VM的架构

 

在AOSP源码中,Dalvik vm源码在dalvik/目录下,被编译成libdvm.so;dalvik/libdex会被编译成libdex.a静态库,作为dex工具使用,dalvik/dexdump是.dex文件的反编译工具;

 

Dalvik虚拟机的架构如图:


Dalvik VM各个子目录的功能:

Dalvikvm:虚拟机命令行调用入口文件的目录,用来解释命令行参数,调用库函数接口等。

Dexdump:生成dex文件反编译查看工具。

Dexlist:生成查看dex文件里所有类的方法的工具。

Dexopt:生成dex优化工具。

Dvz:生成从zygote请求生成虚拟机实例的工具。

Dx:生成从java字节码转换为dalvik机器码的工具。

Hit:生成显示堆栈信息/对象信息的工具。

Libcore:dalvik vm核心类库,提供给上层的应用程序调用。

Libnativehelper:dalvik vm核心库的支持库函数。

 

四、Dalvik vm命令

Dalvik vm支持命令行参数,可以通过系统参数影响虚拟机的行为。

1)  基本命令

通过setprop 设置系统特性

Adb shell setprop name value

这些系统设定是在zygote进程中处理的。

2)  扩展的jni检测

扩展jni检测会导致系统变慢,但可以发现一个bug,这个功能通过-Xcheck:jni命令行激活。

参数ro.kernel.Android.checkjni,dalvik.vm.checkjni覆盖了前一个参数,这两个参数会影响到这个功能

3)  断言

Dalvik vm支持java语言的断言表达式,默认是关闭的,可以通过dalvik –ea 参数设置。

4)  字节码校验和优化

Dalvik vm尝试预校验dex文件中的所有类,降低class的负担,使用优化提升运行性能,上述功能是通过dexopt命令实现的。

两个标记控制jit优化和校验:-Xverify和-Xdexopt。

5)  Dalvik VM的运行模式

包括三种独立的解释内核:快速(fast),可移植(portable),调试(debug),快速解释器是为当前平台优化的,可能包括手动优化的汇编文件;可移植解释器是用C写的,可在广泛的平台的上使用;调试解释器是可移植解释器的变种,包括了支持程序分析(Profiling)和单步。

6)  死锁预测

如果虚拟机以WITH_DEADLOCK_PREDECTION参数编译,死锁预测器会在-Xdeadlockpredict参数中使能。这个特性让虚拟机移植跟踪对象的锁获取顺序,如果程序试图以与之前看到不同的顺序获取一些锁,vm会log一个warning。

7)  Dump堆栈跟踪

Dalvik vm 收到SIGQUIT(kill -3或ctrl -\)时,会为所有线程dump所有的堆栈跟踪,默认写入log,也可以写入一个文件。

Dalvik.vm.stack-trace-file特性指定要将线程堆栈追踪写入的文件名。

8)  Dex文件和校验

VM提供了-Xcheckdexsum参数,如果设置了,在内容使用前所有的dex文件都会进行和校验。

出于性能考虑,优化过的dex文件和校验被取消了。

 

五,ART机制基础

在ART环境下,应用在第一次安装的时候,字节码会预先编译成机器码,使其成为真正的本地应用,这个过程称为预编译(AOT,ahead-of-time),从而加快应用的启动和执行。

ART完全兼容dalvik的字节码格式dex文件。

相对于dalvik垃圾回收的两次暂停(遍历阶段,标记阶段),art只暂停一次。在遍历阶段,应用不需要暂停,标记阶段的暂停时间也缩短了,这是基于packard pre-cleaning技术。

Art源码在AOSP工程下的art/目录。

其中的compiler:主要负责Dalvik字节码到本地代码的转换,编译为libart-compiler.so;

Dex2oat:完成dex文件到ELF文件转换,编译为dex2oat;AOT技术是在编译阶段将java代码翻译成针对目标平台的机器码,但是对于第三方的apk事先不知道它将运行于那个具体的硬件平台,aot就不适合了,所以在apk在配置了art的设备上安装时,会调用一个精简的编译器dex2oat来完成动态的翻译工作。

Runtime:ART运行时源代码,编译为libart.so。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值