01-jvm的运行机制

 

1、编译: java文件编译成class文件字节码

 

平常我们编写的java代码是怎么运行起来的呢? 

通过打一个jar包或者 直接执行java -jar 命令 执行 ,其实 jar文件里面也是编译好的class文件,jvm 相当于一个程序 ,他运行的代码就是已经将java代码编译成  jvm虚拟机能识别的字节码文件。

所以要运行java代码就需要把java文件编译为jvm能够识别的class文件字节码

流程大概如下图:

什么是Class文件

Java字节码类文件(.class)是Java编译器编译Java源文件(.java)产生的“目标文件”。它是一种8位字节的二进制流文件, 各个数据项按顺序紧密的从前向后排列, 相邻的项之间没有间隙, 这样可以使得class文件非常紧凑, 体积轻巧, 可以被JVM快速的加载至内存, 并且占据较少的内存空间(方便于网络的传输)。

Java源文件在被Java编译器编译之后, 每个类(或者接口)都单独占据一个class文件, 并且类中的所有信息都会在class文件中有相应的描述, 由于class文件很灵活, 它甚至比Java源文件有着更强的描述能力。

class文件中的信息是一项一项排列的, 每项数据都有它的固定长度, 有的占一个字节, 有的占两个字节, 还有的占四个字节或8个字节, 数据项的不同长度分别用u1, u2, u4, u8表示, 分别表示一种数据项在class文件中占据一个字节, 两个字节, 4个字节和8个字节。 可以把u1, u2, u3, u4看做class文件数据项的“类型” 。

具体详情可以参考下面的链接 ,这里我们只需要简单了解class文件的概念即可,说白了class文件就是jvm能够识别的运行语言

https://tech.meituan.com/2019/09/05/java-bytecode-enhancement.html

 

 

2、运行JVM: 执行java命令会启动一个jvm进程

 

通常我们执行java -jar  或者java -c 就会  启动一个jvm 进程来负责运行我们的class文件

 

3、类加载:jvm通过类的加载器将编译好的class文件加载到jvm中

类加载的过程:加载-> 验证-> 准备-> 解析-> 初始化-> 使用-> 卸载

1、加载  : 通过类的加载器加载,将类加入 内存中(方法区)

2、验证: 加载到内存后需要对他进行验证才能交给jvm执行

1.文件格式验证
第 1 阶段验证宇节流是否符合 Class 文件格式的规范, 并且能被当前版本的虚拟机处理
2: 元数据验证

第二阶段是对字节码描述的倌息进行语义分析. 以保证其描述的信息符合 Java的要求 


3.字节码验证
  该阶段是整个验证过程中最复杂的一个阶段. 主要目的是通过数据流和控制流分析,
确定程 序语义是否合法的、 符合逻辑的。 在第二阶段对元数据倌息中的数据类型做完校验后,
这个阶段将对类的方法体进行校验分析,保证被校验类的方法在运行时不会做出危害虚拟机
安全的事件
4.符号引用验证
最后一个阶段的校验发生在虚拟机将符号引用转化为直接引用的时候, 这个转化动作将
在连接的第三阶段一解析阶段中发生。 符号引用验证可以看做是对类自身以外( 常量池中
的各种符号引用) 的信息进行匹配性校验。

3、准备

 为类分配内存空间,为变量赋初始值

如:

会为 ReplicaManager   分配内存空间

 并给他的类变量  分配内存空间并赋默认值 0

4、 解析阶段

把符号引用替换为直接引用(知道概念即可,牵涉jvm底层)

5、 初始化(重点)

初始化做了什么?

    1、初始化赋值: 

  public static int flushInterval = 2;   准备阶段静态变量  flushInterval 的初始值为0 , 在 初始化阶段, flushInterval 赋值为2

这种状态会在  获取到配置文件的值后再赋值

 

     2、 static 静态代码块 在该阶段执行

这个时候初始化的时候就会执行 static里面的方法

 

什么时候初始化一个类?

1、包含了main方法 调用

2、比如 new ReplicaManager()”来实例化类的对象 就会触发类的加载到初始化的全过程 然后实例化对象

  3、初始化类的时候如果父类没有初始化,要先初始化他的父类

4、进行反射调用的时候如果类没有进行过初始化,则需要先出法其初始化。

5、当使用JDK1.7的动态语言支持时(不常用)

 

 

4、执行:jvm基于自己的字节码执行引擎,找到main方法开始执行

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学海无涯苦做java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值