likes
comments
collection
share

JVM工作原理与实战(九):类加载器-启动类加载器

作者站长头像
站长
· 阅读数 3

前言

JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了启动类加载器、通过启动类加载器去加载用户jar包等内容。


在Java虚拟机(JVM)中,类加载器负责将类的字节码文件加载到内存中,并生成对应的Class对象。类加载器是Java虚拟机中的重要组成部分,而启动类加载器(Bootstrap ClassLoader)则是其中最核心的类加载器。

JVM工作原理与实战(九):类加载器-启动类加载器

一、启动类加载器

启动类加载器是由Hotspot虚拟机提供的,使用C++编写,是Java类加载器中的顶级类加载器。它的主要职责是加载Java的核心类库,如rt.jar、resources.jar和tools.jar等。这些核心类库包含了Java语言的核心类,如String等。

默认加载的是Java安装目录/jre/lib下的类文件:

JVM工作原理与实战(九):类加载器-启动类加载器

在实际应用中,程序员通常会使用ClassLoader来动态加载第三方类库,或者实现自己的类加载器来满足特定的需求。ClassLoader提供了许多方法来动态加载类,如loadClass()、defineClass()等。这些方法允许程序员在运行时动态地加载类的字节码文件,并生成对应的Class对象。

但是由于启动类加载器位于虚拟机的环境中,而不是在应用程序的代码中,因此程序员无法直接获取到启动类加载器。这是出于安全性的考虑,因为启动类加载器是Java核心类库的加载器,如果允许应用程序代码获取到启动类加载器的引用,可能会被恶意代码利用来加载或修改Java核心类库,导致安全风险。因此,程序员无法在代码中获取到启动类加载器,也无法对其进行操作,这也是为了保证Java虚拟机的安全性和稳定性。

案例:

尝试获取启动类加载器(String类位于JDK下rt.jar包中):

public class BootstrapClassLoaderDemo {
    public static void main(String[] args) throws IOException {
        ClassLoader classLoader = String.class.getClassLoader();
        System.out.println(classLoader);
    }
}

运行结果(无法获取该启动类加载器):

JVM工作原理与实战(九):类加载器-启动类加载器

二、通过启动类加载器去加载用户jar包

在JDK中,类加载器是负责动态加载Java类到JVM中的机制。启动类加载器作为类加载器层次结构的最顶层,负责加载包括java.lang包在内的核心API类。当开发者需要添加或扩展核心类时,必须通过特定的方式来进行。

1.放入jre/lib目录进行扩展

一种直接的方法是将所需的jar包放入JRE/Lib目录下,让启动类加载器能够加载到这个jar包中的类,然而,这种方法并不推荐。主要原因在于,对JDK安装目录中的内容进行更改可能导致不稳定性以及其他未预期的问题。其次,可能会出现因为文件名不匹配而导致无法正常加载的情况发生。

2.使用参数进行扩展

为了更加灵活和可控地扩展JDK,推荐使用命令行参数进行配置。具体来说,可以使用-Xbootclasspath/a:jar包目录/jar包名来指定额外的jar包供启动类加载器加载。这种方式的好处在于,它允许开发者在不更改JDK安装内容的情况下进行扩展,从而保持JDK环境的稳定性。

-Xbootclasspath/a:jar包目录/jar包名

案例:

JVM工作原理与实战(九):类加载器-启动类加载器

public class Test {
    static {
        System.out.println("Test初始化");
    }
}

将该项目打成jar包:

JVM工作原理与实战(九):类加载器-启动类加载器

运行结果:

JVM工作原理与实战(九):类加载器-启动类加载器

放到目录下:

JVM工作原理与实战(九):类加载器-启动类加载器

添加-Xbootclasspath/a:jar包目录/jar包名参数:

-Xbootclasspath/a:jar包目录/jar包名

JVM工作原理与实战(九):类加载器-启动类加载器

加载jar包:

public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.rye.test.Test");
        System.out.println(aClass);
    }
}

运行结果:

JVM工作原理与实战(九):类加载器-启动类加载器

获取该类的类加载器:

public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.rye.test.Test");
        System.out.println(aClass);
        ClassLoader classLoader = aClass.getClassLoader();
        System.out.println(classLoader);
    }
}

获取结果(无法获取启动类加载器):

JVM工作原理与实战(九):类加载器-启动类加载器

对于需要进行核心类扩展的情况,推荐使用命令行参数的方式进行配置,而不是直接修改JDK安装目录的内容。这样可以确保环境的稳定性和避免潜在的类加载问题。


总结

JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了启动类加载器、通过启动类加载器去加载用户jar包等内容,希望对大家有所帮助。