JVM 类加载器
类的生命周期
一个类从被加载到虚拟机内存中开始,到卸载出内存为止,它的生命周期将会经历如下7个步骤:
- 加载 (Loading)
- 验证 (Verification)
- 准备 (Preparation)
- 解析 (Resolution)
- 初始化 (Initialization)
- 使用 (Using)
- 卸载 (Unloading)
其中验证、准备、解析三个部分统称为连接 (Linking),这七个阶段发生的顺序如下图所示
其中前五个部分(加载,验证,准备,解析,初始化)统称为类加载。
加载 (Loading)
加载 (Loading) 是虚拟机类加载阶段的第一个阶段,在加载阶段,Java 虚拟机需要完成以下三件事情:
- 通过一个类的全限定名来获取定义此类的二进制字节流。
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
- 在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。
验证 (Verification)
验证 (Verification) 这一阶段的目的是确保 Class 文件的字节流中包含的信息符合《 Java 虚拟机规范》 的全部约束要求,保证这些信息被当作代码运行后不会危害虚拟机的自身安全。验证阶段大致会完成下面四个阶段的检验动作:
- 文件格式验证
- 元数据验证
- 字节码验证
- 符号饮用验证
准备 (Preparation)
准备阶段是正式为类中定义的变量分配内存并设置类变量初始值的阶段
解析 (Resolution)
解析阶段是 Java 虚拟机将常量池内的符号引用替换为直接引用的过程,主要分为以下四种:
- 类或接口的解析
- 字段解析
- 方法解析
- 接口方法解析
初始化 (Initialization)
初始化阶段是 Java 虚拟机 真正开始执行类中编写的 Java 程序代码。初始化的过程包括执行如下:
- 执行构造器方法。
- static静态变量赋值语句。
- static静态代码块。
类的加载时期
- 当虚拟机启动时,初始化用户指定的主类,就是启动执行的 main 方法所在的类;
- 当遇到用以新建目标类实例的 new 指令时,初始化 new 指令的目标类,就是 new 一 个类的时候要初始化;
- 当遇到调用静态方法的指令时,初始化该静态方法所在的类;
- 当遇到访问静态字段的指令时,初始化该静态字段所在的类;
- 子类的初始化会触发父类的初始化;
- 如果一个接口定义了 default 方法,那么直接实现或者间接实现该接口的类的初始化, 会触发该接口的初始化;
- 使用反射 API 对某个类进行反射调用时,初始化这个类,其实跟前面一样,反射调用要 么是已经有实例了,要么是静态方法,都需要初始化;
- 当初次调用 MethodHandle 实例时,初始化该 MethodHandle 指向的方法所在的类。
JVM 类加载器
http://www.wangxiaohuan.com/2021/03/18/2021-03-18/