乐趣区

关于jvm:jvm学习01类加载过程

一个类从加载到应用,个别会经验上面的这个过程:
加载 -> 验证 -> 筹备 -> 解析 -> 初始化 -> 应用 -> 卸载

1. 加载

编译:

X.java->X.class->JVM

class 汇总的类的加载

双亲委派模型: 子类加载器会请示父类加载器查看层层上询, 下面没加载的, 再层层下派;

  1. 启动类加载器: Bootstrap ClassLoader
  2. 扩大类加载器: Extension ClassLoader
  3. 应用程序类加载器: Application ClassLoader
  4. 自定义类加载器: XXX

自定义加载器 ->Application->Extension->Bootstrap

2. 验证

校验你加载进来的.class 文件内容,是否合乎 Java 虚拟机标准

    1. 格局验证: 0xCAFEBABE 结尾 / 是否有编码以外的字符等
    1. 元数据验证: 比方是否继承了 final 类(不容许的)/ 父类为接口或抽象类的子类, 是否实现了形象办法等;
    1. 字节码验证: 办法调用时任何指令不会跳到办法体以外的的字节码指令上;
    1. 符号援用验证: 符号援用类中的类 / 字段 / 办法的可拜访性(是否能被以后类拜访)

3. 筹备

static 变量: 分配内存空间,设置默认的初始值

byte/short/int/long->0/0L
float/double=0.0f/0.0d
boolean=false
reference=null

4. 解析

符号援用替换为间接援用的过程

间接援用 : 指标的指针 / 绝对偏移量 / 间接定位到指标的句柄
符号援用: class 文件中的字面符号援用;

就是将 classs 文件中的类 / 接口 / 字段 / 办法解析为理论的指标指针 / 绝对偏移量 / 指标句柄等的过程;

起因就是: classs 文件是编译来的; 编译的时候并无奈得悉执行时类 / 接口 / 字段 / 办法的内存地位.

5. 初始化

初始化变量为理论赋值的数据;

static int a = getValue()
在筹备阶段只会给 a 调配空间和给初始值 0, 在初始化阶段才会调用 getValue()来赋值初始化 a;

6. 应用

7. 卸载

退出移动版