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

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

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

image.gif

一、启动类加载器

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

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

image.gif

在实际应用中,程序员通常会使用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);
    }
}

image.gif

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

image.gif

二、通过启动类加载器去加载用户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包名

image.gif

案例:

image.gif

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

image.gif

将该项目打成jar包:

image.gif

运行结果:

image.gif

放到目录下:

image.gif

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

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

image.gif

image.gif

加载jar包:

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

image.gif

运行结果:

image.gif

获取该类的类加载器:

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);
    }
}

image.gif

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

image.gif

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


总结

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

相关文章
|
4月前
|
安全 前端开发 Java
【JVM的秘密揭秘】深入理解类加载器与双亲委派机制的奥秘!
【8月更文挑战第25天】在Java技术栈中,深入理解JVM类加载机制及其双亲委派模型是至关重要的。JVM类加载器作为运行时系统的关键组件,负责将字节码文件加载至内存并转换为可执行的数据结构。其采用层级结构,包括引导、扩展、应用及用户自定义类加载器,通过双亲委派机制协同工作,确保Java核心库的安全性与稳定性。本文通过解析类加载器的分类、双亲委派机制原理及示例代码,帮助读者全面掌握这一核心概念,为开发更安全高效的Java应用程序奠定基础。
93 0
|
2月前
|
存储 监控 算法
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程 ?
尼恩提示: G1垃圾回收 原理非常重要, 是面试的重点, 大家一定要好好掌握
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程  ?
|
3月前
|
安全 Java 应用服务中间件
JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
什么是类加载器,类加载器有哪些;什么是双亲委派模型,JVM为什么采用双亲委派机制,打破双亲委派机制;类装载的执行过程
JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
|
2月前
|
监控 架构师 Java
JVM进阶调优系列(6)一文详解JVM参数与大厂实战调优模板推荐
本文详述了JVM参数的分类及使用方法,包括标准参数、非标准参数和不稳定参数的定义及其应用场景。特别介绍了JVM调优中的关键参数,如堆内存、垃圾回收器和GC日志等配置,并提供了大厂生产环境中常用的调优模板,帮助开发者优化Java应用程序的性能。
|
2月前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
55 2
|
2月前
|
缓存 前端开发 Java
JVM知识体系学习二:ClassLoader 类加载器、类加载器层次、类过载过程之双亲委派机制、类加载范围、自定义类加载器、编译器、懒加载模式、打破双亲委派机制
这篇文章详细介绍了JVM中ClassLoader的工作原理,包括类加载器的层次结构、双亲委派机制、类加载过程、自定义类加载器的实现,以及如何打破双亲委派机制来实现热部署等功能。
50 3
|
3月前
|
Arthas Java 测试技术
JVM —— 类加载器的分类,双亲委派机制
类加载器的分类,双亲委派机制:启动类加载器、扩展类加载器、应用程序类加载器、自定义类加载器;JDK8及之前的版本,JDK9之后的版本;什么是双亲委派模型,双亲委派模型的作用,如何打破双亲委派机制
JVM —— 类加载器的分类,双亲委派机制
|
2月前
|
前端开发 Java 应用服务中间件
JVM进阶调优系列(1)类加载器原理一文讲透
本文详细介绍了JVM类加载机制。首先解释了类加载器的概念及其工作原理,接着阐述了四种类型的类加载器:启动类加载器、扩展类加载器、应用类加载器及用户自定义类加载器。文中重点讲解了双亲委派机制,包括其优点和缺点,并探讨了打破这一机制的方法。最后,通过Tomcat的实际应用示例,展示了如何通过自定义类加载器打破双亲委派机制,实现应用间的隔离。
|
4月前
|
数据库 C# 开发者
WPF开发者必读:揭秘ADO.NET与Entity Framework数据库交互秘籍,轻松实现企业级应用!
【8月更文挑战第31天】在现代软件开发中,WPF 与数据库的交互对于构建企业级应用至关重要。本文介绍了如何利用 ADO.NET 和 Entity Framework 在 WPF 应用中访问和操作数据库。ADO.NET 是 .NET Framework 中用于访问各类数据库(如 SQL Server、MySQL 等)的类库;Entity Framework 则是一种 ORM 框架,支持面向对象的数据操作。文章通过示例展示了如何在 WPF 应用中集成这两种技术,提高开发效率。
63 0
|
4月前
|
开发者 C# Windows
WPF布局大揭秘:掌握布局技巧,轻松创建响应式用户界面,让你的应用程序更上一层楼!
【8月更文挑战第31天】在现代软件开发中,响应式用户界面至关重要。WPF(Windows Presentation Foundation)作为.NET框架的一部分,提供了丰富的布局控件和机制,便于创建可自动调整的UI。本文介绍WPF布局的基础概念与实现方法,包括`StackPanel`、`DockPanel`、`Grid`等控件的使用,并通过示例代码展示如何构建响应式布局。了解这些技巧有助于开发者优化用户体验,适应不同设备和屏幕尺寸。
98 0