类加载机制

       了解jvm中的类加载机制,可以帮助我们更好的理解程序的运行。(由于没有深入了解过jvm,本文以理论为主,日后有实操会进行补充)。

1.类的加载过程

    类的整个加载过程主要分为:加载,连接,初始化,使用和卸载五个阶段,其中连接中有验证,准备,解析三个过程。看一下整个的加载过程示意图:

加载jar包的类 springboot_加载jar包的类 springboot

我们接着了解主要过程中所作的操作:

加载:


类的加载主要通过类加载器来实现,通过不同的类加载器可以加载以下不同来源的二进制数据:


(1)

从本地文件加载class文件;


(2)

从jar包中加载class文件;


(3)

从网络加载class文件;


(4)

将一个java源文件动态编译并执行加载。


连接:


当类被加载以后,系统会生成一个对应的class对象,一个类只会有一个对应的class对象,加载完以后就会进入连接阶段,有以下三个过程:


(1)

验证


验证加载的类是否有正确的内部结构


(2)

准备


为类变量分配内存,设置默认初始值


(3)

解析


将类的二进制数据中的符号替换成直接引用




初始化:

对类变量进行初始化,按照在文件中顺序执行,和准备阶段不同的是,这次会赋值:



public static int VALUE = 10;


    在准备阶段会给VALUE分配空间,并设置默认值0,在初始化阶段则会把10赋给VALUE。




什么时候会进行类的初始化?

当java程序通过以下6种情况使用类或者接口时,会初始化该类或者接口


(1)

创建某个类的实例


(2)

调用某个类的类方法


(3)

访问某个类的类变量,或对类变量进行赋值


(4)

通过反射创建某个类的class对象


(5)

初始化某个类,他的父类也会被初始化


(6)

通过java.exe运行某个类




2.类加载器

jvm启动时,会形成三个类加载器形成的层次结构,同时可以自定义类加载器(插件开发等):


(1)

Bootstrap classLoader:根类加载器


加载java中的核心类


(2)

Extension classLoader:扩展类加载器


加载jre目录下的jar包


(3)

System classLoader:系统类加载器


加载classpath目录下的jar包


    示意图如下:

加载jar包的类 springboot_类加载准备和初始化区别_02

类加载机制:

类的加载机制有以下三种:


(1)

全盘负责,加载某个类的类加载器,也将加载这个类中引用和依赖的类,出来显式改变;


(2)父类委托,类加载器加载类时,会先让父类加载器进行加载,除非父类加载器无法进行加载,才会交由字类加载;


(3)缓存机制,所有加载过的类都是被缓存起来,以后使用时会直接去缓存区寻找。


类加载器加载class过程:


共有八个步骤:


(1)

检测此class是否被缓存过,是的话直接执行第八步,否则执行第二步;


(2)检查父类加载器是否存在,不存在的话(没有父类加载器,要么父类就是根类加载器,要么本身就是根类加载器)执行第四步,存在的话执行第三步;


(3)请求父类加载加载class,成功执行第八步,失败执行第五步;


(4)请求根类加载加载class,成功执行第六步,失败执行第七步;


(5)当前类加载器寻找文件,找到执行第八步,失败执行第七步;


(6)从文件中加载class,成功以后执行第八步;


(7)抛出ClassNotFound异常。


(8)返回对应的java.lang.class对象。