JVM的类加载机制
类加载过程
类加载的过程总共分为以下⼏个步骤:加载,链接(由验证,准备,解析三部分组成),初始化.
加载
加载是类加载的第一个过程,在加载阶段JVM需要完成以下三部分事情:
1.通过一个类的全限定名(如java.util.Scanner)来获取定义此类的二进制字节流.
2.把这个字节流所代表的静态存储结构转化为元数据区的运行时数据结构.
3.在内存中⽣成⼀个代表这个类的java.lang.Class对象,作为⽅法区这个类的各种数据的访问⼊⼝.
链接
验证
验证是链接的第一步,验证主要负责确保Class字节流中所包含的信息符合《Java虚拟机规范》的全部要求,确保这些信息在运行后不会危害虚拟机的安全.
准备
准备阶段是正式为类中定义的变量(静态变量由static修饰)分配内存并设置初始值的阶段.
如:public static int a = 123; 在这个阶段初始化a为int的0,而不是123.
解析
解析阶段是Java虚拟机将常量池内的符号引⽤替换为直接引⽤的过程,也就是初始化常量的过程.
初始化
初始化阶段,Java虚拟机真正开始执⾏类中编写的Java程序代码,将主导权移交给应⽤程序.初始化阶段就是执⾏类构造器⽅法的过程.
双亲委派模型
⼀个类加载器收到了类加载的请求,它⾸先不会⾃⼰去尝试加载这个类,⽽是把这个请求委派给⽗类加载器去完成,每⼀个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层
的启动类加载器中,只有当⽗加载器反馈⾃⼰⽆法完成这个加载请求(它的搜索范围中没有找到所需
的类)时,子加载器才会尝试⾃⼰去完成加载.
这个模型中,Java内部有三个类加载器分别为:
BootstrapClassLoder:负责加载标准库目录下的类.
PlatformClassLoder:负责加载拓展库目录下的类,是BootstrapClassLoder的子类.
ApplicationClassLoder:负责加载第三方库或当前项目库目录下的类,是PlatformClassLoder的子类.
双亲委派模型的工作流程图:
双亲委派模型的优点:
1.避免重复加载类:⽐如A类和B类都有⼀个⽗类C类,那么当A启动时就会将C类加载起来,那么在B类进⾏加载时就不需要在重复加载C类了.
2.安全性:使⽤双亲委派模型也可以保证了Java的核⼼API不被篡改,如果没有使⽤双亲委派模型,⽽是每个类加载器加载⾃⼰的话就会出现⼀些问题,⽐如我们编写⼀个称为java.lang.Object
类的话,那么程序运⾏的时候,系统就会出现多个不同的Object类,⽽有些Object类又是用户自己提供的,因此安全性就不能得到保证了.而使用双亲委派模型可以很好的保护API不被篡改.