跳至主要內容

1、类的加载流程

KindBrave大约 3 分钟

1.Java类的加载流程

总结于https://zhuanlan.zhihu.com/p/268637051open in new window

对于加载流程,简单来说,就是把class字节码中的内容加载到内存当中去。

Java的数据类型分为基本类型和引用类型,基本类型是通过JVM加载的,而引用类型是通过类加载器加载的,我们这里说的类的加载流程,指的应该是引用类型的加载。

类加载过程分为七个步骤:加载、验证、准备、解析、初始化、调用、卸载

其中验证、准备、解析合称为链接部分。

1.1 加载(Loading)

首先,第一个步骤就是加载。这个加载过程就是把class字节码的内容加载到内存当中去,并且得到类的原型--类模板对象

我们通过class字节码中的信息,来得到类模板对象,类模板对象中会存放类的信息,包括类的方法和字段等等,我们可以通过这些信息来调用类的内容。这个过程很容易联想到反射,也确实,Java的反射用到了这里。

这个过程要完成三个事:

  • 根据类名来获取类的二进制数据流
  • 根据类的二进制数据流来得到类模板对象
  • 根据类模板对象来得到类的信息,并且得到Class对象 ->根据类模板对象来创建Class对象

1.1.1 类模板和Class对象的位置

  • 类模板放到(方法区的)元空间里
  • Class对象是一个对象,所以放到堆中

1.2.验证

验证阶段包括四大验证:

  • 格式验证
  • 语义验证
  • 字节码验证
  • 引用验证 符号引用验证

1.2.1 格式验证

格式验证其实是发生在加载过程中的,只有格式验证成功了,类的二进制数据流才会加载到方法区当中,也就是才会在元空间有这个类模板对象

其他三种验证就是在方法区中进行的了

格式验证包括验证魔数、版本号是否受JVM支持~~、是否继承了final类等等~~

1.2.2 语义验证

语义验证用来分析字节码文件的语义是否合规,比如是否继承了final类,抽象类是否有子类实现了等

1.2.3 字节码验证

用来分析字节码是否合规

用来分析字节码跳转位置是否正确

1.2.4 引用验证 符号引用验证

用来判断引用是否存在

1.3.准备

所谓准备阶段,就是为类中的静态变量分配内存空间,并且赋予默认值

需要注意的是,如果一个静态变量是final类型的,它的默认值会在编译阶段进行赋予,在准备阶段只会进行分配内存空间

如果以字符串格式赋给String类型的静态变量,也会在这里分配空间

1.4.解析

解析阶段需要做的就是把符号引用解析为直接引用

1.5.初始化

初始化过程主要是对类中的静态变量进行正确的赋值

1.6.使用

一切完成之后就可以进行使用了

1.7.卸载

当一个类的使命完成后,这个类就会被卸载,但是,一个类被卸载的概率很小