jvm类加载子系统有什么作用
时间: 2023-06-06 07:06:25 浏览: 158
JVM类加载子系统的主要作用是从文件系统或网络中加载需要运行的Java类,并在运行时为它们创建Java对象。它还负责解析类的依赖关系,并在需要时动态地链接它们。此外,JVM类加载子系统还提供安全机制,以确保只有授权的类能够被加载和执行。
相关问题
jvm类加载
### JVM 类加载过程详解
#### 加载(Loading)
当 Java 应用启动时,类加载器子系统会将 `.class` 文件从磁盘读取到内存中。此阶段不仅限于找到所需的类文件并将其字节码加载到方法区,在必要情况下还会创建对应的 `java.lang.Class` 实例对象[^1]。
```java
// 假设有一个名为 MyClass 的类
public class MyClass {
static {
System.out.println("MyClass is being loaded.");
}
}
```
上述代码展示了静态初始化块会在类首次加载时被执行一次。
#### 验证(Verification)
为了确保 Class 文件的字节流中包含的信息符合当前虚拟机的要求,并不会危害虚拟机自身的安全,JVM 对输入的字节流进行数据流和语义分析[^2]。这一步骤对于防止恶意代码破坏现有程序逻辑至关重要。
#### 准备(Preparation)
在此阶段,JVM 将为类变量分配内存空间,并设置默认初始值(例如整数类型的零值)。需要注意的是实例字段并不会在这个阶段初始化其显式赋给它们的具体值;这一操作将在稍后的初始化阶段完成[^3]。
#### 解析(Resolution)
这是将常量池内的符号引用替换为直接引用的过程。所谓符号引用是以一组符号来描述目标,而直接引用则是指向方法区内存布局中的具体位置。解析工作可能发生在初始化之前或期间,取决于具体的实现方式和支持动态绑定的语言特性需求[^4]。
#### 初始化(Initialization)
此时才真正开始执行类中定义的 Java 程序代码(即常量赋值、静态代码块等),目的是让类达到预期的工作状态以便后续正常使用。只有经过正确初始化后,用户自定义的行为才会生效。
#### 使用(Using)与卸载(Unloading)
一旦类已经成功加载并通过了前面提到的所有步骤,它就可以被应用程序所用了。而在某些条件下——比如应用关闭或是永久代/元空间不足的情况下,不再需要的类可以从 JVM 中移除以释放资源。
jvm类加载器面试
### JVM 类加载器相关面试题和知识点解析
#### 1. 什么是类的加载?
类的加载是指将类的字节码文件读入内存,并生成对应的 Class 对象的过程[^1]。类加载过程主要包括以下几个阶段:加载、验证、准备、解析和初始化。每个阶段都有其特定的任务,例如加载阶段负责从文件系统或网络中读取类的二进制数据并将其转换为方法区中的运行时数据结构。
#### 2. 哪些情况会触发类的加载?
类的加载通常由以下几种情况触发:
- 当创建某个类的实例时。
- 当访问某个类的静态变量或为静态变量赋值时。
- 当调用某个类的静态方法时。
- 当使用反射机制对类进行操作时。
- 当初始化某个子类时,其父类尚未被初始化时。
这些场景都会导致虚拟机启动类加载过程。
#### 3. JVM 加载一个类的过程是什么?
JVM 加载一个类的过程可以分为五个主要阶段:
- **加载**:读取类的二进制数据到内存中,并生成对应的 `Class` 对象。
- **验证**:确保加载的类符合 Java 虚拟机规范,不会危害虚拟机的安全性。
- **准备**:为类的静态变量分配内存,并设置默认初始值。
- **解析**:将类中的符号引用替换为直接引用。
- **初始化**:执行类的初始化代码,包括静态块和静态变量的赋值操作[^4]。
#### 4. 什么时候会为变量分配内存?
对于类的静态变量,在类加载的准备阶段会为其分配内存并设置默认值。而对于实例变量,则在对象实例化时分配内存。此外,局部变量的内存分配则发生在方法栈帧创建时[^1]。
#### 5. JVM 的类加载机制是什么?
JVM 的类加载机制基于双亲委派模型(Parent Delegation Model)。该模型规定,当一个类加载器收到类加载请求时,它首先会将请求委派给父类加载器,只有在父类加载器无法加载该类时,才会尝试自己加载。这种机制可以保证核心类库的安全性和一致性[^2]。
#### 6. 双亲委派机制可以打破吗?为什么?
双亲委派机制可以通过自定义类加载器来打破。例如,某些框架(如 OSGi)通过实现自己的类加载逻辑,允许不同模块之间加载相同名称但不同版本的类。打破双亲委派机制的主要原因是满足特定场景下的需求,例如隔离类加载环境或加载特定版本的类[^3]。
```java
// 自定义类加载器示例
public class MyClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] classData = loadClassData(name);
if (classData == null) {
throw new ClassNotFoundException();
} else {
return defineClass(name, classData, 0, classData.length);
}
} catch (Exception e) {
throw new ClassNotFoundException();
}
}
private byte[] loadClassData(String className) {
// 实现类字节码加载逻辑
return null;
}
}
```
#### 7. 扩展类加载器的作用是什么?
扩展类加载器(Extension ClassLoader)负责加载位于 `JAVA_HOME/jre/lib/ext` 目录及其子目录中的类文件。这些类通常是 Java 平台的扩展库,提供了比核心类库更通用但不那么重要的功能。
---
###
阅读全文
相关推荐















