专栏导航
JVM工作原理与实战
RabbitMQ入门指南
从零开始了解大数据
目录
专栏导航
前言
一、类加载器介绍
二、类加载器的分类
1.Java代码实现的类加载器
2.Java虚拟机底层源码实现的类加载器
3.默认的类加载器层次(JDK8及之前的版本)
总结
前言
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了类加载器、类加载器的分类等内容。
一、类加载器介绍
类加载器(ClassLoader)是Java虚拟机(JVM)提供的一种机制,用于动态加载类和接口的字节码数据到内存中。类加载器是Java虚拟机的重要组成部分,它负责在运行时将类的字节码文件加载到内存中,并创建对应的Class对象,以供JVM解释和执行。
类加载器在加载阶段主要完成以下任务:
- 加载:类加载器首先会从文件系统、JAR文件或网络加载类的字节码文件,将其转换为可执行的Java类。
- 链接:链接阶段包括验证、准备和解析三个子阶段。验证是为了确保被加载的类文件是安全的,准备是分配内存并初始化为默认值,解析是将符号引用转换为直接引用。
- 初始化:在初始化阶段,类加载器会执行类构造器方法(<clinit>()),该方法是由编译器自动收集类中的所有类变量的赋值动作和静态代码块集合来的。
本地接口JNI,全称为Java Native Interface,为Java提供了一种与其他语言编写的代码进行交互的机制。这使得Java可以调用非Java语言(如C、C++等)编写的函数和方法。在HotSpot类加载器中,JNI主要用于与使用C++编写的Java虚拟机内部方法进行交互。
二、类加载器的分类
类加载器可以分为两类:Java代码实现的类加载器和Java虚拟机底层源码实现的类加载器。
1.Java代码实现的类加载器
Java代码实现的类加载器主要是通过继承ClassLoader这个抽象类来实现的。JDK中默认提供了多种处理不同渠道的类加载器,比如从文件系统、JAR文件或网络加载类的类加载器。程序员也可以根据需求自定义类加载器,以实现特定的类加载逻辑。
查看ClassLoader的子类(项目中的类加载器):
2.Java虚拟机底层源码实现的类加载器
Java虚拟机底层源码实现的类加载器,例如Hotspot中的类加载器,是用底层语言(如C++)实现的。这些类加载器在Java虚拟机的实现中扮演着重要的角色,负责在程序运行时加载基础类,以确保这些核心类的可靠性和稳定性。
由于基础类是Java平台的核心组成部分,因此它们的加载必须非常可靠和高效。Java虚拟机底层源码实现的类加载器直接与操作系统交互,使用底层语言的性能优势来加载类。这些类加载器通常与虚拟机的其他部分紧密集成,以确保正确的类加载和初始化过程。
这些类加载器通常具有以下特点:
- 高性能:由于使用底层语言实现,这些类加载器可以直接与操作系统交互,避免了Java代码到本地代码的转换开销,从而提供了更高的性能。
- 可靠性:由于直接与操作系统交互,这些类加载器具有更强的可靠性和稳定性,能够更好地处理异常情况和资源管理。
- 安全性:由于直接集成到虚拟机的安全机制中,这些类加载器提供了更强的安全性保障,能够防止恶意代码的加载和执行。
3.默认的类加载器层次(JDK8及之前的版本)
对于JDK8及之前的版本,默认的类加载器层次结构如下:
- 启动类加载器(Bootstrap):这是最顶层的类加载器,负责加载Java的核心类库,如java.lang包中的类等。它是用C++编写的,是Java虚拟机底层实现的一部分。
- 扩展类加载器(Extension):这是Bootstrap的子类加载器,负责加载Java的扩展类库。它是ClassLoader的子类,通过调用父类的loadClass()方法来加载类。
- 应用程序类加载器(Application):这是Extension的子类加载器,负责加载应用程序的类。它是ClassLoader的子类,通过调用父类的loadClass()方法来加载类。
使用Arthas查看类加载器:
classloader
classloader命令将 JVM 中所有的 classloader 的信息统计出来,并可以展示继承树,urls 等。
参数名称 | 参数说明 |
---|---|
[l] | 按类加载实例进行统计 |
[t] | 打印所有 ClassLoader 的继承树 |
[a] | 列出所有 ClassLoader 加载的类(谨慎使用) |
[c:] | ClassLoader 的 hashcode |
[classLoaderClass:] | 指定执行表达式的 ClassLoader 的 class name |
[c: r:] | 用 ClassLoader 去查找 resource |
[c: load:] | 用 ClassLoader 去加载指定的类 |
案例:
启动以下程序:
public class Test {
public static final int i = 1;
public static void main(String[] args) throws IOException {
Test test = new Test();
System.in.read();
}
}
启动Arthas,并选择Test:
java -jar arthas-boot.jar
运行结果:
输入classloader命令将 JVM 中所有的 classloader 的信息统计出来:
classloader
统计结果:
结果解析:
BootstrapClassLoader | 启动类加载器(C++实现) |
ArthasClassloader | Arthas类加载器 |
ExtClassLoader | 扩展类加载器 |
DelegatingClassLoader | 反射代理类加载器 |
AppClassLoader | 应用程序类加载器 |
总结
JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了类加载器、类加载器的分类等内容,希望对大家有所帮助。