Androidandroid 知识整理

Java&Android 基础知识梳理(7) - And

2017-11-19  本文已影响647人  泽毛

一、Dalvik 虚拟机

DalvikGoogle公司自己设计用于Android平台的Java虚拟机,它是Android平台的重要组成部分,支持dex格式的Java应用程序的运行。

Dalvik作为面向Linux、为嵌入式操作系统设计的虚拟机,主要负责完成 对象生命周期管理、堆栈管理、线程管理、安全和异常管理,以及垃圾回收等。Dalvik充分利用Linux进程管理的特定,对其进行了面向对象的设计,使得可以 同时运行多个进程,而传统的Java程序通常只能运行一个进程。

1.1 Dalvik 虚拟机和 JVM 的对比

区别一

区别二

区别三

1.2 Dalvik 虚拟机特点

1.3 Dalvik 系统架构

1.3.1 dex 文件结构

.class 文件与 .dex 文件对比

.dex文件结构和.class文件结构差异的地方很多,但从携带的信息上看,.dex.class文件是一致的:

虽然.dex文件的结构很紧凑,但想要运行时的性能得到进一步提升,还需要对dex文件进行进一步优化。优化主要针对以下几个方面:

.dex文件经过优化后文件大小会膨胀,大约增加到原来的1~4倍。对于内置应用,一般在系统编译后,便会生成优化文件odex(Optimized dex)。一个Android应用程序,需要经过以下过程才可以在Dalvik虚拟机上运行:

.apk 文件的产生过程

1.3.2 Dalvik 类加载器

一个dex文件需要类加载器加载原生类和Java类,然后通过解释器根据指令集对Dalvik字节码进行解释和执行。Dalvik类加载器使用mmap函数,将dex文件映射到内存中,通过普通的内存读取操作即可访问dex文件,然后解析dex文件内容并加载其中的类到哈希表中。

解析 dex

总的来说,dex文件可以抽象为三个部分:头部、索引、数据。通过头部可以知道索引的位置和数目,以及数据区的起始位置。将dex文件映射到内存后,Dalvik会调用dexFileParse函数对其进行分析,分析的结果放到DexFile数据结构中。DexFile中的baseAddr指向映射区的起始位置,pClassDefs指向class索引的起始位置。为了加快class的查找速度,还创建一个哈希表,对class名字进行哈希并生成索引。

加载 class

解析工作完成后就进行class的加载,加载的类需要用ClassObject数据结构来存储。

typedef struct Object {
    ClassObject* clazz;  // 类型对象
    Lock lock;           // 锁对象
} Object;

其中clazz指向ClassObject对象,还包含一个Lock对象。如果其它线程想要获取它的锁,只有等这个线程释放。Dalvik每加载一个class都会对应一个ClassObject对象,加载过程会在内存中分配几个区域,分别存放directMethodvirtualMethodsfieldifield。这些信息从dex文件的数据区中读取。字段Field的定义如下:

struct Field {
    ClassObject* clazz;    //所属类型
    const char* name;      // 变量名称
    const char* signature; // 如“Landroid/os/Debug;”
    u4 accessFlags;        // 访问标记
    
    #ifdef PROFILE_FIELD_ACCESS
        u4 gets;
        u4 puts;
    #endif
};

待得到class索引后,实际的加载由loadClassFromDex来完成。首先它会读取class的具体数据,分别加载directMethodvirtualMethodifieldsfield,然后为ClassObject数据结构分配内存,并读取dex文件的相关信息。加载完成后,将加载的class通过dvmAddClassToHash函数放入哈希表,以方便下次查找;最后,通过dvmLinkClass查找该类的超类,如果有接口类则加载相应的接口类。

1.3.3 Dalvik 解释器

对于任何虚拟机来说,解释器无疑是核心的部分,所有的Java字节码都经过解释器解释执行。由于Dalvik解释器的效率很重要,Android分别实现了C语言版和各种汇编语言版的解释器。解释器通常是循环执行,需要一个入口函数调用处理程序执行第一条指令,而后每条指令执行时引出下一条指令,通过函数指针调用处理程序。

二、Dalvik 虚拟机和 ART 虚拟机对比

Android 4.4之后,Google开始使用了更加优秀的ART虚拟机来替换Dalvik虚拟机,下面我们就来对比一下这两者之间的区别。

2.1 Dalvik

打包的过程中 会先将.java等源码通过javac编译成.class文件,再通过dx.class文件转换成Dalvik虚拟机执行的.dex文件。

应用启动的时候 先将.dex文件 转换成机器码,又因为65536的文件,导致在应用冷启动的时候有一个合包的过程,最后的结果就是app的启动时间有可能变慢,这就是Dalvik虚拟机的JIT(Just in Time)特性。

2.2 ART

ART除了兼容了Dalvik虚拟机的特性之外,还有一个很好的特性AOT(Ahead of Time),这个特性就是把 .dex 文件转换成机器码 这个步骤提前到了 应用安装 的时候,ART虚拟机将.dex文件转换成可直接运行的.oat文件,ART虚拟机天生支持多dex,所以也不会有一个合包的过程,因此会极大的提升APP冷启动速度。

2.3 ART 虚拟机的优缺点

优点:

缺点:

三、参考文献

理解 Android 虚拟机体系结构
Android Dalvik 虚拟机和 ART 虚拟机对比

Dalvik 虚拟机简要介绍和学习计划
Dalvik 虚拟机的启动过程分析
Dalvik 虚拟机的运行过程分析

深入理解 Dalvik 虚拟机 - Android应用进程启动过程分析
深入理解 ART 虚拟机 - 虚拟机的启动
深入理解 ART 虚拟机 - ART 的函数运行机制
深入理解 Dalvik 虚拟机 - 解释器的运行机制
深入理解ART虚拟机 - ImageSpace的加载过程分析


更多文章,欢迎访问我的 Android 知识梳理系列:

上一篇 下一篇

猜你喜欢

热点阅读