1 

官方简介

Java虚拟机规范官方文档https://docs.oracle.com/javase/specs/index.html其中以java8的为https://docs.oracle.com/javase/specs/jvms/se8/html/index.html看下官方的介绍的一节The Java Virtual MachineJava虚拟机是Java平台的基石。是java实现硬件和操作系统的独立性(也就是无关性),生成极小体积的编译代码,以及保护用户免受恶意程序攻击的的关键技术组成部分。

Java虚拟机是一种抽象计算机器。
像真正的计算机一样,它有一个指令集以及在运行时各种内存区域。
使用虚拟机实现编程语言是相当普遍的;
最著名的虚拟机可能是 P-Code machine of UCSD Pascal。

Java虚拟机的第一个原型实现是在Sun Microsystems inc.完成的,它在手持设备上仿真实现了Java虚拟机指令集,该设备类似于现在的个人数字助理(PDA)。

Oracle现在已经将许多java虚拟机实现应用于 移动设备 pc 服务器等领域,但是Java虚拟机不局限于任何特定的实现技术、主机硬件或主机操作系统。
也不局限于特定的代码执行方式,虽然不强求使用解释器来执行程序,但是也可以通过将它的指令集编译成一个实际的CPU来实现。它也可以在微代码microcode实现,也可以直接在CPU中实现。
Java虚拟机对Java编程语言一无所知,只知道一种特定的二进制格式,class文件格式。一个class文件包含Java虚拟机指令集(或者称之为字节码bytecode)和符号表,以及其他辅助信息。

基于安全方面的考虑,Java虚拟机在class文件中施加了许多强制性的语法和结构化约束,凡是能用class文件正确表达出来的编程语言,都可以放在Java虚拟机里面执行。由于它是一个通用的、机器无关的执行平台,所以其他语言的实现者都可以考虑将Java虚拟机作为那些语言的交付媒介。 2 

java的组成部分

  • Java语言规范

  • Java 应用程序编程接口 API

  • Java class文件格式规范

  • Java虚拟机

java语言规范java语言规范决定了你要怎么书写你的源代码。也就是java的语法句法词法结构组成,数据类型长度等,对于java语言本身的描述。比如主函数需要是public static void main(String[] args){ 为什么使用public而不是common表示公用?这就是java语言规范的作用。 java应用程序编程接口Java应用程序API 也就是java设计者提供的基本的功能方法,比如访系统资源。
API之主要目的是提供应用程序与开发人员以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
提供API所定义的功能的软件称作此API的实现。API是一种接口,故而是一种抽象。应用程序接口为:"电脑操作系统(Operating system)’或‘程序库’提供给应用程序调用使用的代码、
其实所有的功能也都是依赖操作系统本身的,比如读取文件、获取文件的属性。如果一个操作系统,本身就没有网络通信的功能,你是不可能在上面完成网络通信程序的开发的。 Java class文件格式规范编译后被Java虚拟机执行的一种二进制文件格式,这是一种统一的明确的格式 一般以文件的形式存储,其实就是java虚拟机的"机器语言"。 Java虚拟机读取class文件,解析class文件并执行,实际运行java的机器。一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。 编写任何一个程序你都会用到这四个技术领域。
 3 

无关与相关的辩证关系

JVM是平台相关的,不同的平台有不同的虚拟机。但是她在不同的平台上提供统一一致的JVM虚拟指令集,对具体的平台进行抽象封装不管运行在何种平台,他们提供一致性的操作与访问形式。从JVM本身的平台相关性,转变成为JAVA语言的平台无关性。 class文件是源代码,编译后的平台无关的二进制文件格式,不依赖于特定的硬件与操作系统表示形式。是JVM可以识别执行的语言,相当于JVM的机器语言。也就是说,不管何种语言,如果一旦能够编译成为符合规范的class文件格式,就能够被JVM进行执行! 这就相当于实现了语言无关性。 可以说,java设计者的野心很大。class文件 与JVM的结合,语言无关加上平台无关。JVM|虚拟机简介(一)_java   4 

java语言实现与运行原理

再回头看下java技术体系,可以很清晰的看得出来:

  1. java的语言实现与运行原理;

  2. Java语言规范 和 Java 应用程序编程接口 API 提供了使用Java语言解决问题的方式;

  3. Java class文件格式规范 和Java虚拟机 则约定了Java的运行原理;

class文件是对源代码的编译,不仅仅具有语言无关性的好处。源代码是以对人友好的方式,class文件是机器友好的,通过对原始文件进行特殊的处理与转换,能够提高运行的性能,将一部分工作前置。
class文件既然是对于源代码的转换描述,自然是会涉及到java中的各种数据类型,方法调用,常量等等的描述与表示。JVM既然是解析class文件进行解析执行,自然是需要解析class文件,并且能够读取验证文件的格式以及语法格式,然后进行装载运行。 所以说想要了解Java的运行原理,最基本的两个部分就是:class文件的结构组成以及JVM的运行区域内存的管理。Java语法中所有的一切都要能够表示出来,比如:数据类型、引用类型、基本类型、字段属性、方法、公有私有、静态、非静态如何表示描述?以及必要的信息,比如当前对象的this等等。
某种程度上来说 class文件就是源代码针对于java虚拟机的"注解版" ,将你知道的语法表示出来,然后还有潜在的隐藏的信息,比如父类信息等。 对于一个已经定义好的class文件,JVM需要进行一系列严格的验证。因为一个class文件可能不是由一个标准的编译器生成的也可能被别人恶意篡改过,所以JVM必须验证。验证之后还需要进行装载把数据信息装载到内存中,然后进行初始化等等。这就是JVM涉及到的部分,所以说想要弄明白java的运行原理需要了解清楚class文件的结构以及JVM的运行内存划分。  5 

使用javap查看编译后的文件

javap -v HelloWolrd.class  查看上图中的信息不必较真,我也是随便标注了个别比较好辨别的点。但是你完全可以发现:class文件对于源文件的完整表述:类信息、字段信息、方法信息、涉及到的常量与其他类的调用等等;
class文件是一张巨大的表。信息是单独存放的,可以把行号#XXX 理解成地址。如下图所示,从头不断地根据地址信息串联起来,知道最终的叶子数据信息,形成一张巨大的信息表。比如再次重申:这些就相当于JVM的机器语言了,有数据,有指令,JVM要做的就是解析执行了。当然,是一项很复杂的工作。ps:

我是说相当于,javap看到的内容,是对信息进行了一定程度的美化,class文件不是这样子的,下图才是class文件 十六进制编辑器打开的样子:

JVM|虚拟机简介(一)_java_02


另外javap还有很多其他命令,可以通过-help参数查看。JVM|虚拟机简介(一)_java_03

https://mp.weixin.qq.com/s/6YNp3Q6ZZyeDWZd-KLR1gg