JVM 类加载子系统在干什么?

embedded/2025/2/13 4:16:43/

JVM 类加载子系统是什么?

类加载子系统(Class Loader Subsystem)是 JVM 负责 加载、链接和初始化 .class 文件的组件。它的主要作用是将字节码文件加载进 JVM 并准备执行

类加载器(ClassLoader)是 字节码的搬运工,负责 找到、加载、解析和初始化字节码,最终让 JVM 执行它。

类加载子系统 = 类加载器 + 其他步骤

类加载子系统主要包括三个阶段:

  1. 加载(Loading)由类加载器完成,找到 .class 文件并加载到方法区。
  2. 链接(Linking) → 验证(检查字节码)、准备(分配静态变量)、解析(符号引用替换)。
  3. 初始化(Initialization) → 执行 static 代码块和静态变量赋值。

1. 为什么需要类加载子系统?

当你写一个 Java 类,比如:

public class Demo {public static void main(String[] args) {System.out.println("Hello JVM!");}
}

编译后会生成一个 Demo.class 文件,这个文件并不能直接运行,而是需要 JVM 加载 进内存,解析并执行,这就是 类加载子系统的作用


2. 类加载子系统的主要任务

类加载子系统的作用主要包括:

  1. 加载(Loading):将 .class 文件从磁盘/网络/其他来源加载进 JVM
  2. 链接(Linking)
    • 验证(Verification):检查 class 字节码是否合法(避免恶意代码)。
    • 准备(Preparation):为静态变量分配内存,赋默认值。
    • 解析(Resolution):将符号引用替换为直接引用(将 String.class 转换为内存地址)。
  3. 初始化(Initialization):执行类的 static 代码块和 static 变量初始化代码。

3. 类加载过程(深入细节)

(1) 加载(Loading)

JVM 通过 类加载器(ClassLoader).class 文件加载到内存,类信息存放在 方法区
来源

  • 磁盘(如 C:\classes\Demo.class
  • 网络(如 http://example.com/Demo.class
  • 运行时生成(如动态代理 Proxy

示例:

Class<?> clazz = Class.forName("com.example.Demo");

这个调用会触发 Demo.class 加载


(2) 连接(Linking)

加载完成后,JVM 需要确保类的正确性,并为其分配必要的内存

(a) 验证(Verification)
检查 .class 文件是否符合 JVM 规范,防止字节码攻击。

(b) 准备(Preparation)
静态变量 分配内存并初始化默认值(不执行赋值语句)。

public class Test {static int a = 10;
}
  • 准备阶段a = 0 (默认值)
  • 初始化阶段a = 10(执行赋值)

(c) 解析(Resolution)
符号引用java/lang/String)转换成 直接引用(指向方法区 String.class 的地址)。


(3) 初始化(Initialization)

真正执行 static 代码块 和 static 变量赋值

public class Test {static int a = 10;static {System.out.println("Class initialized");}
}
  • 赋值 a = 10
  • 执行 static 代码块,打印 "Class initialized"

类初始化的时机 只有第一次使用该类(创建对象、访问静态变量等)时,才会初始化:

Test t = new Test(); // 触发初始化

4. 类加载器(ClassLoader)

JVM 提供不同层次的类加载器:

  1. Bootstrap ClassLoader(启动类加载器)
    • 加载核心类库rt.jar
    • 例:java.lang.String
  2. Extension ClassLoader(扩展类加载器)
    • 加载 lib/ext 目录下的类
    • 例:javax.crypto.Cipher
  3. Application ClassLoader(应用类加载器)
    • 加载 classpath 下的应用代码
    • 例:com.example.Demo
  4. 自定义 ClassLoader
    • 通过 URLClassLoaderdefineClass 自定义类加载逻辑。

示例:

ClassLoader classLoader = Test.class.getClassLoader();
System.out.println(classLoader); // AppClassLoader

5. 结论

  • 类加载子系统 负责 .class 文件加载到 JVM,并执行必要的初始化操作。
  • 类加载有 加载(Loading)、链接(Linking)和初始化(Initialization) 三个阶段。
  • 类加载器 负责查找并加载 .class 文件,JVM 默认有 启动类加载器、扩展类加载器、应用类加载器,也可以自定义类加载器

总结一句话

类加载子系统是 JVM 的入口,负责加载、校验和初始化类,使其能够被 JVM 运行。


http://www.ppmy.cn/embedded/161776.html

相关文章

计算机毕业设计——Springboot的疫情网课管理系统

&#x1f389;**欢迎来到琛哥的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 琛哥&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 琛哥在深度学习任务中展现出卓越的能力&a…

STC 51单片机62——极简 4x4x4光立方

本次设计一个非常简洁的光立方&#xff0c;省略了限流电阻&#xff0c;用两节1.5V干电池直接驱动。 主控芯片&#xff1a;STC8H1K28&#xff0c;属于STC中比较新的系列单片机&#xff0c;管脚够用&#xff0c;也没有很多的空余。 电源直接使用带开关的电池盒&#xff0c;内含2…

BUU35 [DASCTF X GFCTF 2024|四月开启第一局]EasySignin 100 【gopher打mysql】

先注册一个账号&#xff0c;登进去以后发现有三个功能&#xff0c;康好康的图片现在不行&#xff0c;推测得是admin用户才行 点击更新当前用户密码&#xff0c;没让我们输入旧密码&#xff0c;抓包后更改username&#xff0c;这样我们更新的就是admin用户的密码了 利用gopher…

数​字​政​通​一​面

1. 请尽可能详细地说明&#xff0c;虚拟dom是什么&#xff0c;它的产生是为了解决哪些问题的&#xff1f;你的回答中不要写出示例代码。 虚拟DOM&#xff08;Virtual DOM&#xff09; 定义 虚拟DOM是一个轻量级的JavaScript对象&#xff0c;它是真实DOM&#xff08;Document…

关于防火墙运维面试题

一、防火墙基础概念类 1. 请详细阐述防火墙在网络安全体系中的具体作用及核心原理。 以下是防火墙在网络安全体系中的具体作用及核心原理的详细阐述&#xff1a; 防火墙在网络安全体系中的作用 访问控制 限制非法访问&#xff1a;防火墙可以根据预设的规则&#xff0c;允许…

Wiki文档转换为Word技术

一、技术背景与目标 Wiki系统导出的文档通常以HTML格式存在,且内容分散在多个文件中,每个页面对应一个HTML文件。然而,Microsoft Word(Word)在处理HTML文件时,仅支持单个HTML文件的导入。因此,为了将Wiki导出的内容转换为Word可识别的格式,必须将分散的HTML文件整合为一…

DeepSeek图解10页PDF

以前一直在关注国内外的一些AI工具&#xff0c;包括文本型、图像类的一些AI实践&#xff0c;最近DeepSeek突然爆火&#xff0c;从互联网收集一些资料与大家一起分享学习。 本章节分享的文件为网上流传的DeepSeek图解10页PDF&#xff0c;免费附件链接给出。 1 本地 1 本地部…

SpringBoot项目练习

重点学习技术&#xff1a; Nginx、Spring Session、Swagger、lombok、Redis、junit 流程&#xff1a; 建库-->建表&#xff08;导入表结构&#xff09; 新建maven项目-->pom文件-->application.yml-->启动类-->前端静态资源配置 登录功能&#xff08;创建实体…