vlambda博客
学习文章列表

类加载机制 | 双亲委派模型

来源:章鱼猫

链接: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类不会被加载。

  • 避免重复加载,父类加载器已经加载过,则子类不需要再次加载。

常见问题

  1. 为什么要打破双亲委派?

    防止类冲突,做资源隔离。(不同的类加载器加载相同的class文件是不同的类)

  2. 如何打破双亲委派?

    使用用户自定义类加载器就可以打破。

  3. 打破双亲委派举例?

    Tomcat、JDBC、部分热部署框架等都打破了双亲委派。


— END