类加载机制
# 类加载过程以及加载机制
类加载器的种类:
启动类加载器(Bootstrap ClassLoader),是虚拟机自身的一部分,用来加载Java_HOME/lib/目录中的,或者被 -Xbootclasspath 参数所指定的路径中并且被虚拟机识别的类库;
其他类加载器:
扩展类加载器(Extension ClassLoader):负责加载\lib\ext目录或Java. ext. dirs系统变量指定的路径中的所有类库;
应用程序类加载器(Application ClassLoader)。负责加载用户类路径(classpath)上的指定类库,我们可以直接使用这个类加载器。一般情况,如果我们没有自定义类加载器默认就是用这个加载器。
类加载器 就是根据指定全限定名称将class文件加载到JVM内存,转为Class对象。
加载过程:
加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载
验证 -> 准备 -> 解析 这三步合起来称为 连接
1.加载
加载简单来说分为三步。
第一步:获取二进制字节流也就是上面的class文件。
第二步:将静态的存储结构转换为方法区中的运行时数据结构。
第三步:生成一个对象放入java堆中,做为对方法区的引用。
(类的加载就是将class文件中的二进制数据读取到内存中,然后将该字节流所代表的静态数据结构转化为方法区中运行的数据结构,并且在堆内存中生成一个java.lang.Class对象作为访问方法区数据结构的入口)
2.验证
验证主要是检验如下的几项是否正确
class文件的表示(魔数),class文件的版本号,class文件的每个部分是否正确(字段表、方法表等),验证常量池(常量类型、常量类型数据结构是否正确,utf-8是否标准),元数据验证(父类验证,继承验证,final验证),字节码(指令)验证,符号引用验证(是否能根据符号找到对应的字段、表、方法等)
如果一项不对,就会验证失败。
3.准备
准备阶段为类变量分配内存 和设置类变量初始化。这个过程中,只对static类变量进行内存分配,这个时候只是分配内存,没有进行复制,所有的类变量都是初始化值。如果是final的话,会直接对应到常量池中。会在准备阶段直接赋值。
4.解析
解析阶段是读符号引用进行解析。将符号引用解析为直接引用(指向目标的指针或者偏移量)。主要涉及到的解析有类,接口,字段,方法等。
5.初始化
初始化就是执行<clinte><linte>
方法的过程, <clinte>
对静态变量,静态代码块进行初始化,<linte>
对类进行初始化。
6.使用
使用阶段就是使用这个class。
7.卸载
卸载阶段就是不在使用,将class给卸载。