java虚拟机的运行机制,java程序的运行过程

Class文件:

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在class文件之中,中间没有任何分隔符。

Class文件格式采用一种类似于C语言结构体的伪结构来存储。这种伪结构只有无符号数和表。无符号数用来保存数字,索引引用,数量值或者按照UTF8编码构成字符串值。表是由多个无符号数或者多个表构成的。

 

Class 文件需要加载到java虚拟机之中才能继续运行。

虚拟机把class文件加载到内存,然后对数据进行校验,转换解析和初始化,最终生成可以被虚拟机直接使用的java类型

与那些编译时进行连接工作的语言不同,java的加载和连接都是在程序运行时确定的。

 java虚拟机的运行机制,java程序的运行过程_第1张图片

加载阶段,虚拟机完成三件事情:

通过一个类的全限定名来获取定义此类的二进制字节流

将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构

在java堆中生成一个代表这个类的java.Lang.class对象,作为方法区这些数据的访问入口。

 

加载阶段完成之后,虚拟机外部的二进制字节流就按照虚拟机所需的格式存储在方法区之中

验证阶段:

 

准备:

正式为类变量分配内存,并设置类变量初始值,这些内存都将在方法区中进行分配

 

解析阶段:将常量池内的符号引用替换为直接引用的过程

 

初始化:在准备阶段,变量已经被赋过一次系统系统要求的值,而初始化阶段则是根据程序员通过程序制定的主观计划去初始化变量和其他资源;也可以看成在执行类构造器的方法

 

虚拟机设计团队将类加载阶段中“通过一个类的全限定名来获取定义此类的二进制字节流

”这一步放到java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码叫做“类加载器”。

!!对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在java虚拟机中的唯一性。

 

方法调用:方法调用不等于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法),但是还不涉及方法内部的具体执行过程。程序运行时,方法调用时最频繁的操作,但是class文件的编译过程不包含传统编译连接中的连接步骤,一切方法调用在class文件里都是符号引用而已,而不是实际运行时的内存布局的入口地址,需要在类加载期间甚至到运行期间才能确定目标方法的直接引用。

在java中,符合“编译期可知,运行期不可变”要求的方法主要有静态方法和私有方法两大类,他们都适合在类加载阶段进行解析。

 

在class文件格式和执行引擎这里,用户程序能够影响的并不多,class文件以何种方式进行存储,类型何时加载,如何连接,以及虚拟机如何执行字节码命令都是虚拟机直接控制的行为,用户程序无法对其改变。能通过程序改变的主要就是字节码生成和类加载器这两部分的功能。

你可能感兴趣的:(java)