JVM类加载器

发布于:2024-12-06 ⋅ 阅读:(98) ⋅ 点赞:(0)

目录

类加载器的定义与作用

类加载器的分类

类加载的过程

类加载器的加载机制

五、类加载器的应用场景

自定义类加载器


类加载器(Class Loader)是Java虚拟机(JVM)的一部分,负责将Java类的二进制代码加载到内存中,并转换为可执行的Java字节码。它是Java语言的重要特性之一,为Java应用程序提供了动态加载和运行时扩展的能力。以下是对类加载器的详细解析:

类加载器的定义与作用

  1. 定义:类加载器是一个用来加载类文件的类,它工作在类加载过程中的加载这一步,通过类的全类名获得该类的二进制字节流然后加载到JVM。每个类都会有一个引用指向加载它的类加载器。
  2. 作用:负责将.class文件(存储的物理文件)加载到内存中,通过加载字节码数据放入内存转换成byte[],接下来调用虚拟机底层方法将byte[]转换成方法区和堆中的数据。

类加载器的分类

类加载器通常可以分为以下三种:

  1. 启动类加载器(Bootstrap ClassLoader)

    • 由C++实现,是虚拟机的一部分。
    • 主要负责加载JVM自身需要的类,即负责加载JAVA_HOME/jre/lib目录下的核心类库。
    • 是最顶层的类加载器,没有父类加载器。
    • 无法在Java代码中直接获取到。
  2. 扩展类加载器(Extension ClassLoader)

    • 由Java实现,具体实现类是sun.misc.Launcher$ExtClassLoader。
    • 主要加载JAVA_HOME/jre/lib/ext目录中的类。
    • 父类加载器是启动类加载器,但在Java代码中通过getParent()方法获取其父类加载器会返回null,因为启动类加载器不是Java实现的。
  3. 应用程序类加载器(Application ClassLoader)

    • 也称为系统类加载器(System ClassLoader),由Java实现,具体实现类是sun.misc.Launcher$AppClassLoader。
    • 主要加载classpath下的类,包括用户自定义的类以及第三方Jar包中的类。
    • 父类加载器是扩展类加载器。

类加载的过程

类加载过程分为加载、链接、初始化三个阶段,其中链接过程又细分为验证、准备、解析三个步骤。

  1. 加载:将类的二进制数据流解析为方法区内的数据结构(Java类模型),并创建java.lang.Class类的实例,表示该类型。
  2. 验证:确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全。
  3. 准备:为类的类变量(被static修饰的变量)分配内存,并设置默认初始化值。
  4. 解析:将类的二进制数据流中的符号引用替换为直接引用。
  5. 初始化:根据程序员通过程序制定的主观计划去初始化类变量和其他资源。对类的静态变量、静态代码块执行初始化操作。如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。

类加载器的加载机制

类加载器使用一种称为双亲委派模型(Parent Delegation Model)的机制来加载类。该模型根据一定的规则将类加载的任务委派给父加载器,直到最终委派给启动类加载器进行加载。如果父加载器无法加载该类,才由当前加载器自行加载。这种机制保证了类的加载是从上到下的,避免了重复加载和类的版本冲突问题。同时,通过双亲委派机制,JVM可以对类加载的层次结构进行管理和控制,从而确保类的安全性。

五、类加载器的应用场景

  1. 企业级应用:在大型企业级应用中,可能需要使用到不同的类加载器来加载不同来源的类,以实现类的隔离和动态加载。
  2. SPI机制:Java的SPI(Service Provider Interface)机制允许服务提供者通过配置文件来提供服务的实现类,而服务的使用者则通过类加载器来加载这些实现类。
  3. 类的热部署:在一些应用场景中,可能需要在不重启应用的情况下动态地替换某些类。这时可以使用自定义类加载器来实现类的热部署。
  4. Tomcat类的隔离:在Tomcat等Web服务器中,为了实现不同Web应用之间的类隔离,通常会为每个Web应用分配一个独立的类加载器。

自定义类加载器

用户可以通过继承java.lang.ClassLoader类来自定义类加载器,需要重写findClass方法,实现自定义类加载规则。自定义类加载器可以灵活加载类,实现各种特定需求,比如从网络下载类文件、解密等。