首页 > Python资料 博客日记
JVM类加载器大比拼:谁才是Java程序的真正主宰?
2024-03-17 05:00:07Python资料围观139次
主页传送门:📀 传送
概述
JVM(Java虚拟机)的类加载器是Java的核心组件之一,负责将Java字节码文件加载到JVM中,并将其转换为可以执行的Java类。
类加载器的主要职责:
- 加载类:根据类的全限定名,将类的字节码文件加载到JVM中,并为其创建一个Class对象。
- 链接类:验证类的字节码是否符合Java虚拟机规范,并准备类的静态变量(即初始化静态变量为默认值)。
- 初始化类:执行类的静态初始化代码,包括静态变量初始化和静态代码块执行。
类加载器定义
类加载器是Java虚拟机(JVM)中的一个组件,它的主要作用是将Java源代码编译成可执行的字节码,并将其加载到JVM中。
类加载器在Java中扮演着关键的角色,它们使Java具备了动态加载和隔离不同类的能力。具体来说,类加载器负责从文件系统、网络或其他来源读取类文件(.class文件),并将其转换为JVM中的可执行代码。这个过程分为两个步骤:首先是加载类,通过读取类文件并创建一个代表该类的Class对象;其次是链接类,包括验证、准备和解析类文件中的符号引用。
类加载器还遵循双亲委派模型,即子类加载器在收到类加载请求时,首先将请求委派给父类加载器,只有在父类加载器无法完成加载请求时,子类加载器才会尝试自己去加载。这种机制可以保证Java核心API的稳定性和防止某些安全问题。
类加载器种类
类加载器主要有三种:启动类加载器、扩展类加载器和系统类加载器。启动类加载器负责加载Java核心类库,扩展类加载器负责加载java.ext.dirs系统属性中指定的目录或JDK安装目录的lib/ext子目录下的类库,而系统类加载器则负责从Classpath环境变量中加载应用相关的类。
启动类加载器
Bootstrap ClassLoader
(启动类加载器)是Java虚拟机(JVM)中的一种特殊类加载器,它是JVM的内部组成部分,主要负责加载Java核心类库,如java.lang
包中的类以及其他基础的类,这些类通常是JVM运行所必需的类。
Bootstrap ClassLoader
的主要特点:
-
加载核心类库:
Bootstrap ClassLoader
负责加载JVM运行时环境所需的核心类库,这些类库通常包括Java标准库中的一些基础类,如Object类、String类等。这些类在JVM启动时就会被加载,因此无法通过普通的类加载器重新加载或替换。 -
不是普通的ClassLoader:
Bootstrap ClassLoader
不是普通的Java类加载器,它通常是用本地代码(C/C++)实现的,与普通的Java类加载器不同。这使得它能够加载基础类库,而不受Java应用程序的类加载器体系的影响。 -
无法被替换: 由于
Bootstrap ClassLoader
加载的类是JVM运行所必需的核心类库,它们不能被普通的Java类加载器替换或重新加载。这确保了JVM的稳定性和安全性。
Bootstrap ClassLoader
是JVM的内部组件,负责加载JVM运行所需的核心类库,具有特殊的地位和特点,通常不会被普通的Java应用程序代码所涉及。
示例:
public class Main {
public static void main(String[] args) {
// 使用核心类
String message = "Hello, World!";
System.out.println(message);
// 使用Object类
Object obj = new Object();
// 等等...
}
}
扩展类加载器
Extension ClassLoader
(扩展类加载器)是Java虚拟机(JVM)的一个重要组成部分,它的主要职责是加载Java标准扩展库中的类和用户自定义的扩展类。
Extension ClassLoader
的主要职责和工作方式:
-
加载扩展类库:
Extension ClassLoader
负责加载位于JRE(Java Runtime Environment)的lib/ext
目录下的JAR文件中的类。这些JAR文件包含了Java标准扩展库,例如Java Cryptography Extension(JCE)或Java Naming and Directory Interface(JNDI)等。 -
工作方式:
Extension ClassLoader
是JVM中的一个普通的Java类加载器,它的工作方式与其他普通的类加载器类似,但有一点不同,它是通过父类加载器的方式工作的。通常情况下,Extension ClassLoader
的父类加载器是Bootstrap ClassLoader
。这意味着它首先会尝试从Bootstrap ClassLoader
加载类,如果找不到类,它才会尝试从自己的类路径中加载。 -
类路径:
Extension ClassLoader
的类路径通常包括JRE的lib/ext
目录下的JAR文件。这个类路径是通过系统属性java.ext.dirs
来指定的。 -
用户自定义扩展类: 除了加载标准扩展库,Extension ClassLoader还可以加载用户自定义的扩展类,只要这些类位于
java.ext.dirs
目录下或其子目录中。这允许开发人员将自己的扩展类添加到JRE,以扩展Java的功能。
Extension ClassLoader
的主要职责是加载Java标准扩展库中的类和用户自定义的扩展类,它通过委派给Bootstrap ClassLoader
来加载标准扩展库中的类,同时也可以加载用户自定义的扩展类。这有助于扩展Java的功能和功能。
示例:
public class Main {
public static void main(String[] args) {
// 使用Extension ClassLoader加载自定义扩展类
MyExtensionClass extensionClass = new MyExtensionClass();
extensionClass.printMessage();
}
}
系统类加载器
Application ClassLoader
(应用程序类加载器),也被称为System ClassLoader
,是Java虚拟机(JVM)中的一种类加载器。它的主要作用是加载应用程序开发者编写的Java类,这些类通常位于应用程序的类路径(Classpath)下。
Application ClassLoader
在应用程序中的作用:
-
加载应用程序类:
Application ClassLoader
负责加载应用程序开发者编写的Java类,包括应用程序的主类和所有相关的库和依赖。这些类通常位于应用程序的类路径中,可以通过CLASSPATH环境变量或者-classpath
命令行参数来指定。 -
应用程序隔离性:
Application ClassLoader
为不同的Java应用程序提供了隔离性。不同的Java应用程序可以拥有自己独立的类加载器实例,这样它们不会相互干扰,即使它们使用相同的类名也不会发生冲突。这有助于确保应用程序的独立性和隔离性。 -
动态加载:
Application ClassLoader
允许应用程序在运行时动态加载类。这对于插件化架构和动态模块加载非常有用,应用程序可以根据需要加载额外的类,而无需重新启动。 -
类版本控制:
Application ClassLoader
还负责管理和控制已加载类的版本。如果应用程序需要升级某个类,它可以确保加载新版本的类而不会与旧版本发生冲突。
Application ClassLoader
在应用程序中的主要作用是加载应用程序开发者编写的Java类,提供应用程序隔离性,支持动态加载,并管理类的版本控制。这是Java应用程序在JVM中正常运行的关键组成部分。
示例:
public class Main {
public static void main(String[] args) {
/*
使用Application ClassLoader加载类
Application ClassLoader会自动加载应用程序类
*/
MyClass myObject = new MyClass();
myObject.printMessage();
}
}
class MyClass {
public void printMessage() {
System.out.println("Hello from MyClass!");
}
}
自定义类加载器
除了上述三种类加载器,还有一种比较特殊的类加载器——自定义类加载器(Custom Class Loader
)。自定义类加载器允许开发者自己实现类加载器的逻辑,以满足特定场景的需求。这些类加载器需要继承自ClassLoader
类,并重写findClass()
方法来指定加载过程。例如,可以实现一个加载指定路径下所有jar文件的类加载器,或者实现一个加密/解密字节码的类加载器等。想了解更多自定义类加载器的可以看上文动态类加载
继承关系
在Java中,类加载器的继承关系为:ClassLoader
->SecureClassLoader
-> URLClassLoader
-> AppClassLoader
-> ExtClassLoader
-> BootstrapClassLoader
。其中,AppClassLoader
和ExtClassLoader
是系统类加载器和扩展类加载器的实例,而BootstrapClassLoader
是启动类加载器的实例。开发者可以通过继承ClassLoader
类或URLClassLoader
类来实现自定义类加载器。
图解如下:
需要注意的是,Java虚拟机规范并没有强制要求实现这三种类型的类加载器,但是大多数Java虚拟机实现都会提供这三种类型的类加载器。
特点
JVM类加载器有以下特点:
- 分层:JVM类加载器分为多个层次,每个层次都有自己的类加载器和父级类加载器。开发者可以创建自定义类加载器,并将其添加到任何级别的层次中。
- 隔离:每个类加载器都有自己的命名空间,其中包含由其加载的所有类。因此,不同类加载器可以加载具有相同名称的类,但这些类的实例不会相互干扰。
- 动态性:开发者可以创建自定义类加载器来动态地加载Java类。例如,Web服务器可以使用自定义类加载器来加载Web应用程序所需的Java类。
- 缓存:JVM会缓存已加载的类的元数据信息,以便在再次需要时快速访问。
类加载机制
类名称空间
判断类是否“相等”?
任意一个类,都由加载它的类加载器和这个类本身一同确立其在 Java 虚拟机中的唯一性,每一个类加载器,都有一个独立的类名称空间。
因此,比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个 Class 文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那么这两个类就必定不相等。
这里的“相等”,包括代表类的 Class 对象的 equals() 方法、isInstance() 方法的返回结果,也包括使用 instanceof 关键字做对象所属关系判定等情况。
性能优化
- 减少类加载器的数量:在应用程序中使用过多的类加载器会降低性能,因此应该尽量减少类加载器的数量。
- 使用缓存:对于已经加载的类,可以使用缓存技术进行存储和管理,避免重复加载同一个类。Java中的类加载器可以缓存已经加载的类,因此使用缓存可以减少加载时间和提高性能。
- 使用类预加载技术:对于需要经常使用的类,可以使用类预加载技术,通过预先加载类来提高类的访问速度。可以使用静态变量或者单例模式等技术来预加载类。
- 优化类的加载顺序:对于应用程序中频繁使用的类,可以优化它们的加载顺序,使其先加载,从而减少应用程序的启动时间。
- 使用轻量级类库:Java中有许多轻量级的类库,可以提高应用程序的性能。这些类库通常具有更小的代码库和更快的加载速度,因此可以提高应用程序的性能。
- 使用JIT优化:Java HotSpot虚拟机中自带JIT编译器,可以将字节码编译为本地机器码,从而提高性能。
参考文献
虚拟机规范
深入理解Java虚拟机
openjdk
如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏 🙌一起讨论 你的支持就是我✍️创作的动力! 💞💞💞
标签:
相关文章
最新发布
- 【Python】selenium安装+Microsoft Edge驱动器下载配置流程
- Python 中自动打开网页并点击[自动化脚本],Selenium
- Anaconda基础使用
- 【Python】成功解决 TypeError: ‘<‘ not supported between instances of ‘str’ and ‘int’
- manim边学边做--三维的点和线
- CPython是最常用的Python解释器之一,也是Python官方实现。它是用C语言编写的,旨在提供一个高效且易于使用的Python解释器。
- Anaconda安装配置Jupyter(2024最新版)
- Python中读取Excel最快的几种方法!
- Python某城市美食商家爬虫数据可视化分析和推荐查询系统毕业设计论文开题报告
- 如何使用 Python 批量检测和转换 JSONL 文件编码为 UTF-8
点击排行
- 版本匹配指南:Numpy版本和Python版本的对应关系
- 版本匹配指南:PyTorch版本、torchvision 版本和Python版本的对应关系
- Python 可视化 web 神器:streamlit、Gradio、dash、nicegui;低代码 Python Web 框架:PyWebIO
- 相关性分析——Pearson相关系数+热力图(附data和Python完整代码)
- Python与PyTorch的版本对应
- Anaconda版本和Python版本对应关系(持续更新...)
- Python pyinstaller打包exe最完整教程
- Could not build wheels for llama-cpp-python, which is required to install pyproject.toml-based proj