前言
我进入 Androird 行业也有一段时间,目前负责项目开发方面的工作,难免会用到虚拟机实现代码运行,最近我也一直在思考,虚拟机是以哪种方式实现的,底层逻辑又是怎样的?于是在网上查阅了相关的资料,结合自身的见解,将之整合在了一起,接下来我们就来了解一下虚拟机的相关知识
虚拟机的前身
● 众所周知,Android 最开始面世时,使用的开发语言是 Java,而 Java 是运行在 Java 虚拟机上的,即 JVM;那么为什么 Google 要单独设计一套新的 Dalvik 虚拟机来执行 Android 程序呢?
● 可能是为了解决移动端设备上软件运行效率问题,可能是 JVM 虚拟机无法满足当时移动端的使用场景,也可能是为了规避与 Oracle 公司的版权纠纷问题,最终 Google 专门为 Android 平台设计了一套虚拟机来运行 Android 程序,它就是 Dalvik Virtual Machine(Dalvik 虚拟机)
● 随着 Android 发展至今,虽然目前开发 Android 程序的语言已经越来越多样性,如 Java,Kotlin,Dart,Flutter 等等,但无论使用哪种语言开发 Android,最终都需要运行在虚拟机上,本篇文章将站在 Android 虚拟机的视角来分析 Android 程序的运行原理
Dalvik 虚拟机概述及特点
Google 于 2007 年底正式发布了 Android SDK, Dalvik 虚拟机也正式进入我们的视野,而 Dalvik 命名的由来是取至其作者 丹·伯恩斯坦(Dan Bornstein) 曾居住过一个名叫 Dalvik 的小渔村
Dalvik 虚拟机作为 Android 平台的核心组件,拥有如下几个特点:
● 体积小,占用内存空间小
● 专有的 DEX 可执行文件格式,体积更小,执行效率更快
● 常量池采用 32 位索引值,寻址类方法名、字段名、常量更快
● 基于寄存器架构,并拥有一套完整的的指令系统
● 提供了对象生命周期管理、堆栈管理、线程管理、安全和异常管理以及垃圾回收等重要功能
所有的 Android 程序都运行在 Android 系统进程里,每个进程对应着一个 Dalvik 虚拟机实例
Java 虚拟机概述及特点
JVM 是 Java Virtual Machine(Java虚拟机)的缩写,是 JRE 的一部分;它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM 有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统;Java 虚拟机 JVM 是属于 JRE 的,而现在我们安装 JDK 时也附带安装了 JRE (当然也可以单独安装JRE)
JVM 拥有如下几个特点:
● JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行
● Java虚拟机实例负责运行一个Java程序。当启动一个Java程序时,一个虚拟机实例就诞生了。当程序结束,这个虚拟机实例也就消亡。在 Java虚拟机规范中,一个虚拟机实例的行为是分别按照子系统、内存区、数据类型和指令来描述的,这些组成部分一起展示了抽象的虚拟机的内部体系结构
● 作为一种编程语言的虚拟机,实际上不只是专用于Java语言,只要生成的编译文件匹配JVM对载入编译文件格式要求,任何语言都可以由JVM编译运行
Java虚拟机与Java语言并没有必然的联系,他只与特定的二进制文件格式—Class文件格式所关联,Class文件中包含了Java虚拟机指令集(或者称为字节码,Bytecodes)和符号表,还有一些其他辅助信息
Dalvik 虚拟机与 Java 虚拟机的区别
从 Dalvik 虚拟机的特点我们可以看出 Dalvik VM 和 JVM 还是有许多的不同点的,两者并不兼容,他们显著的不同点主要有以下几个方面:
● Java 虚拟机运行的是 Java 字节码,Dalvik 虚拟机运行的是 Dalvik 字节码; 传统的 Java 程序经过编译,生成 Java 字节码保存在 .class 文件中,Java 虚拟机通过解码 .class 文件中的内容来运行程序
● 而 Dalvik 虚拟机运行的是 Dalvik 字节码,所有的 Dalvik 字节码由 Java 字节码转换而来,并被打包到一个 DEX(Dalvik Executable) 的执行的文件中,Dalvik 虚拟机通过解释 DEX 文件来执行这些字节码
总结
本质上,Dalvik也是一个Java虚拟机;但它特别之处在于没有使用JVM规范;大多数Java虚拟机都是基于栈的结构,而Dalvik虚拟机则是基于寄存器。基于栈的指令很紧凑
例如,Java虚拟机使用的指令只占一个字节,因而称为字节码;基于寄存器的指令由于需要指定源地址和目标地址,因此需要占用更多的指令空间
Dalvik虚拟机的某些指令需要占用两个字节,基于栈和基于寄存器的指令集各有优劣;一般而言,执行同样的功能,前者需要更多的指令(主要是load和store指令),而后者需要更多的指令空间;需要更多指令意味着要多占用CPU时间,而需要更多指令空间意味着数据缓冲(d-cache)更易失效
Android架构师之路还很漫长,与君共勉
PS:有问题欢迎指正,欢迎大家点赞评论,可以在评论区留下你的建议和感受
网友评论