Dalvik虚拟机学习之路

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wdx_1136346879/article/details/86540937

Dalvik虚拟机学习之路
Dalvik虚拟机,是Google等厂商合作开发的Android移动设备平台的核心组成部分之一。它可以支持已转换为.dex(即“Dalvik Executable”)格式的Java应用程序的运行。.dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。(值得一提的是,从Android 5.0版起,Android Runtime(ART)替换Dalvik成为系统内默认虚拟机。)

	1.Dalvik虚拟机和Java虚拟机的区别
	Dalvik虚拟机使用的是dex(Dalvik Executable)格式的类文件,而Java虚拟机使用的是class格式的类文件。

Dalvik虚拟机使用的指令是基于寄存器的,而Java虚拟机使用的指令集是基于堆栈的。
每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释器下得以执行。
有一个特殊的虚拟机进程Zygote,他是虚拟机实例的孵化器。它在系统启动的时候就会产生,它会完成虚拟机的初始化、库的加载、预制类库和初始化的操作。如果系统需要一个新的虚拟机实例,它会迅速复制自身,以最快的速度提供给系统。对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域。
2.Dalvik的工作流程
Dalvik虚拟机支持已转换为.dex(即Dalvik Executable)格式的Java应用程序的运行,.dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。(dx 是一套工具,可以将 Java .class 转换成 .dex 格式. 一个dex档通常会有多个.class。由于dex有时必须进行最佳化,会使档案大小增加1-4倍,以ODEX结尾。)

在这里插入图片描述

2.1 java-class
首先读取源码,一个一个字节的读取进来,找出来我们Java定义的关键字,比如if ,else,for,while,finally,等这个步骤就是叫做词法分析过程

第二步:检查第一步读取出来的关键字是否符合Java语言规范,比如if后面跟的是不是一个Boolean类型的表达式,这个过程就叫做语法分析

第三步:经过以上2个步骤词法分析,语法分析,基本上已经按照Java规范了,接下来就是这些拼装的代码要表达什么意思,也就是语义分析

在这里插入图片描述

2.2 class-dex
传统Class文件是一个Java源码文件会生成一个.Class文件,而Android是把所有Class文件进行合并,优化,然后生成一个最终的class.dex,如此,多个Class文件里如果有重复的字符串,当把它们都放到一个dex文件的时候,只要一份就可以了嘛。
在这里插入图片描述

2.3 dex-odex
odex文件就是dex文件具体在某个系统(不同手机,不同手机的OS,不同版本的OS等)上的优化。odex文件的优化依赖系统上的几个核心模块(由BOOTCLASSPATH环境变量给出,一般是/system/framework/下的jar包,尤其是core.jar)。

在这里插入图片描述
3.内存管理
物理内存即移动设备上的RAM,当启动一个Android程序时,会启动一个Dalvik VM进程,系统会给它分配固定的内存空间(16M,32M不定),这块内存空间会映射到RAM上某个区域。然后这个Android程序就会运行在这块空间上。Java里会将这块空间分成Stack栈内存和Heap堆内存。stack里存放对象的引用,heap里存放实际对象数据。
Native Heap就是在Native Code中使用malloc等分配出来的内存,这部分内存是不受Java Object Heap的大小限制的,也就是它可以自由使用,当然它是会受到系统的限制。但是有一点需要注意的是,不要因为Native Heap可以自由使用就滥用,因为滥用Native Heap会导致系统可用内存急剧减少,从而引发系统采取激进的措施来Kill掉某些进程,用来补充可用内存,这样会影响系统体验。
4.垃圾处理
Dalvik虚拟机可以自动回收那些不再使用了的Java Object,也就是那些不再被引用了的Java Object。垃圾自动收集机制将开发者从内存问题中解放出来,极大地提高了开发效率,以及提高了程序的可维护性。

GC工作模型图:
在这里插入图片描述

5.进程与线程管理
Dalvik虚拟机运行在Linux操作系统之上。我们知道,Linux操作系统并没有纯粹的线程概念,只要两个进程共享同一个地址空间,那么就可以认为它们同一个进程的两个线程。Linux操作系统提供了两个fork和clone两个调用,其中,前者就是用来创建进程的,而后者就是用来创建线程的。

Dalvik虚拟机线程的创建过程

在这里插入图片描述
Dalvik部分源码分析

start指令对应的代码:
在这里插入图片描述
dvmStartup指令对应的代码图
在这里插入图片描述
new-instance指令对应的代码图
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wdx_1136346879/article/details/86540937