1、类的加载流程
1.Java类的加载流程
总结于https://zhuanlan.zhihu.com/p/268637051
对于加载流程,简单来说,就是把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.卸载
当一个类的使命完成后,这个类就会被卸载,但是,一个类被卸载的概率很小