本文大量借鉴了周志明先生的著作《深入理解java虚拟机:JVM高级特性》以及网上相当多优秀的资料和见解。
无关性
平台无关性
cpu(指令集)、操作系统的多样化是现实,在可预见的未来也不会改变,那么如何让编程语言实现平台无关性?例如在windows写的代码在linux上运行,这个需要应该说相当现实,大部分程序员的工作界面应该都是windows或者mac,但linux在服务器端又占据了主流。在计算机领域,任何一个问题都可以通过引入中间层来解决。
java一开始的设计初衷就是write once,run anywhere,而这一切依赖于字节码和java虚拟机。
通常情况下,开发人员在windows上安装了x86版本的jdk(java development kit),jdk包含了jre(java runtime environment),java虚拟机就属于jre的一部分,那么开发并发布一个程序的过程就是如下:
- 在windows上通过IDE/文本编辑器编写代码,得到.java文件;
- 通过IDE或者jdk/bin下javac命令编译源代码,得到.class文件即字节码;
通过IDE调试/运行或者jdk/bin下java命令运行.class文件,此时windows启用一个jvm进程,这个jvm是windows本机安装的jvm,它负责把字节码解释翻译成windows能直接运行的机器码。
我们可以看到解决java语言平台无关性问题的关键就是引入通用的class文件和平台相关的jvm。
class文件规范从第一个版本至今,变化其实很少,而且大部分是利用已有的设计做了扩展,相比之下jvm的发展变化要更多而快。发展至今出现了众多的产品,其中我们最常用的是hotspot,可以通过java -version看到,有一些是商用的,有一些是开源的,不同的jvm都遵从了jvm规范设计,但在内存区域抽象划分、GC时的垃圾收集器等具体实现方面有所不同,从而使用不同的使用场景,众多的java平台贡献者和使用者针对jvm的研究和优化付出了大量心血让java持续成为最流行的编程语言之一。花费这么多心思搞的这么牛逼的jvm,如果能支持其他编程语言岂不是很好?java的前辈们一开始就把语言无关性纳入了考虑。
语言无关性
java虚拟机的设计在一开始就考虑了跨语言的特性,java虚拟机上运行的是class文件,jvm规范中对class文件的语法、语义做出了约定,这意味着只要一个编程语言最终交付给java虚拟机的是符合jvm规范的class字节码文件,那这个文件就可以在jvm上运行。现如今,像kotlin、clojure等编程语言其实都可以运行在java虚拟机之上。
接下来,看看class文件以及字节码。
class文件
class文件格式
任何一个Class文件都对应着唯一的一个类或接口的定义信息,但是反过来说,类或接口并不一定都得定义在文件里(譬如类或接口也可以动态生成,直接送入类加载器中)。
Class文件是一组以8个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用8个字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8个字节进行存储。根据《Java虚拟机规范》的规定,Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:“无符号数”和“表”。后面的解析都要以这两种数据类型为基础,所以这里必须先解释清楚这两个概念。
- 无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。
- 表是由多个无符号数或者其他表作为数据项构成的复合数据类型,为了便于区分,所有表的命名都习惯性地以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上也可以视作是一张表,这张表由表6-1所示的数据项按严格顺序排列构成。
to be continued.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。