类加载机制
了解jvm中的类加载机制,可以帮助我们更好的理解程序的运行。(由于没有深入了解过jvm,本文以理论为主,日后有实操会进行补充)。
1.类的加载过程
类的整个加载过程主要分为:加载,连接,初始化,使用和卸载五个阶段,其中连接中有验证,准备,解析三个过程。看一下整个的加载过程示意图:
我们接着了解主要过程中所作的操作:
加载:
类的加载主要通过类加载器来实现,通过不同的类加载器可以加载以下不同来源的二进制数据:
(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包
示意图如下:
类加载机制:
类的加载机制有以下三种:
(1)
全盘负责,加载某个类的类加载器,也将加载这个类中引用和依赖的类,出来显式改变;
(2)父类委托,类加载器加载类时,会先让父类加载器进行加载,除非父类加载器无法进行加载,才会交由字类加载;
(3)缓存机制,所有加载过的类都是被缓存起来,以后使用时会直接去缓存区寻找。
类加载器加载class过程:
共有八个步骤:
(1)
检测此class是否被缓存过,是的话直接执行第八步,否则执行第二步;
(2)检查父类加载器是否存在,不存在的话(没有父类加载器,要么父类就是根类加载器,要么本身就是根类加载器)执行第四步,存在的话执行第三步;
(3)请求父类加载加载class,成功执行第八步,失败执行第五步;
(4)请求根类加载加载class,成功执行第六步,失败执行第七步;
(5)当前类加载器寻找文件,找到执行第八步,失败执行第七步;
(6)从文件中加载class,成功以后执行第八步;
(7)抛出ClassNotFound异常。
(8)返回对应的java.lang.class对象。