流程图

https://www.processon.com/diagraming/60c1aafb1e085306cf6c540b

流程解释

加载阶段

加载阶段是类加载过程的第一个阶段。在这个阶段,JVM 的主要目的是将字节码从各个位置(网络、磁盘等)转化为二进制字节流加载到内存中,接着会为这个类在 JVM 的方法区创建一个对应的 Class 对象,这个 Class 对象就是这个类各种数据的访问入口

类加载器

启动类加载器

Booostrap ClassLoader:主要负责加载java安装目录lib下的核心类

扩展类加载器

Extension ClassLoader:主要加载java安装目录lib\ext目录下的类

应用程序类加载器

App ClassLoader:主要负责加载ClassPath环境变量指定的路径的类

双亲委派

简介

流程

https://www.processon.com/diagraming/60c1aafb1e085306cf6c540b

使用

验证阶段

在把.class文件加载到内存之前根据java虚拟机的规范判断.class文件是否符合规范

准备阶段

给类分配一定的内存空间,并给类变量分配空间和赋值

注意事项

  • 只给类变量分配内存空间和初始化值,不会给成员变量分配空间和初始化值
  • 给类变量初始化值得时候,不是使用代码里面赋的值,而是使用该数据类型的默认值
  • 如果是被final修饰的类变量会直接使用代码中赋予的值,而不是使用默认值
    1
    2
    3
    4
    // 类变量 (在准备阶段的时候值为0)
    public static int a =100
    // 类成员变量
    public int b=10;

解析阶段

这个阶段是将符号引用替换为直接引用
符号引用:因为在编译城.class文件时,此时jvm并不知道所应用类的地址,所以用一组符号来代替
直接引用:如果有了直接引用,那么被应用的对象一定会被加载到内存中;
直接引用可以是
直接指向目标的指针(指向对象、类变量和类方法的指针)
相对偏移值(指向实例的变量、方法的指针)
一个可以间接定位到对象的句柄

初始化阶段(重要)

触发的条件

  • 遇到new、getstatic、putstatic、invokestatic这四个字节码指令时,如果类没有进行实例化,则需要进行初始化。

    触发场景

    • 使用new对象实例化对象时;
    • 读取或设置一个类的静态字段(被final修饰的除外)
    • 调用一个类的静态方法时
  • 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过实例化,则进行初始化
  • 当实例化一个类时。如果发现父类没有进行初始化,则触发父类的初始化

当jvm完成初始化后,jvm便从入口方法执行程序

卸载

当执行完代码后,jvm便开始销毁创建的对象,最后负责执行的jvm退出内存