类加载机制 | 双亲委派模型
来源:章鱼猫
链接:https://lishaojie1993.gitee.io/
类加载机制
一个类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历:
加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸载(Unloading),七个阶段,其中验证、准备、解析三个部分统称为连接(Linking)。
加载过程
加载:将二进制 class 文件加载到内存。
连接
验证:确保类加载的正确性(文件格式、元数据、字节码、符号引用等)
准备:给类的静态变量分配内存,并赋予默认值。
解析:把符号引用转化为直接引用。
初始化:为静态变量赋予正确的初始值,也就是实际值。
默认值和实际值的区别:
默认值:比如boolean的默认值是false;int的默认值是0;
实际值:就是程序员在初始化时真正想要分配给对象的值。
类加载器
把类加载阶段中“通过一个类的全限定名来获取描述该类的二进制字节流”的这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需的类。实现这个动作的代码被称为“类加载器”(Class Loader)。
种类
启动类加载器(Bootstrap Classloader):加载 JAVA_HOME/jre/lib 下的核心类库。
扩展类加载器(Extension ClassLoader):加载 JAVA_HOME/jre/lib/ext 下的jar文件。
系统类加载器(Application ClassLoader):加载 classpath 下的文件。(最常用)
自定义类加载器(必须继承 ClassLoader):负责加载用户自定义路径下的类包。
作用
将类的字节码文件从JVM外部加载到内存中(确定一个类的唯一性)
提供隔离特性,为中间件开发者提供便利(例如Tomcat)
双亲委派
简单来说,就是优先委托父类加载器加载,父类加载器都不能加载时才自己加载。
作用
安全,防止核心类被随意修改,比如自己写的String类不会被加载。
避免重复加载,父类加载器已经加载过,则子类不需要再次加载。
常见问题
为什么要打破双亲委派?
防止类冲突,做资源隔离。(不同的类加载器加载相同的class文件是不同的类)
如何打破双亲委派?
使用用户自定义类加载器就可以打破。
打破双亲委派举例?
Tomcat、JDBC、部分热部署框架等都打破了双亲委派。