JVM基础---java类加载机制(类的生命周期,类加载器,双亲委派模型)

devtools/2025/2/22 5:11:46/

文章目录

  • 类的生命周期
    • 类的加载:查找并加载类的二进制数据
    • 验证
    • 准备
    • 解析
    • 初始化
  • 类加载器
    • 启动类加载器(Bootstrap ClassLoader)
    • 扩展类加载器(Extension ClassLoader)
    • 应用程序类加载器(Application ClassLoader)
    • 自定义类加载器(User-Defined ClassLoader)
  • 双亲委派模型
    • 工作原理
    • 优点
    • 打破双亲委派
    • 打破双亲委派


类的生命周期

类加载的过程包括了加载验证准备解析初始化五个阶段。在这五个阶段中,

加载验证准备初始化这四个阶段发生的顺序是确定的,解析阶段则不一定,它在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也成为动态绑定或晚期绑定)。另外注意这里的几个阶段是按顺序开始,而不是按顺序进行或完成,因为这些阶段通常都是互相交叉地混合进行的,通常在一个阶段执行的过程中调用或激活另一个阶段。

img

类的加载:查找并加载类的二进制数据

  • 任务:将类的字节码文件(.class 文件)加载到内存中。

img

  • 具体步骤

    1. 通过类的全限定名(包名 + 类名)查找字节码文件。
    2. 将字节码文件读取到内存中。
    3. 在内存中生成一个代表该类的 java.lang.Class 对象。
  • 加载.class文件的方式

    • 从本地系统中直接加载
    • 通过网络下载.class文件
    • 从zip,jar等归档文件中加载.class文件
    • 从专有数据库中提取.class文件
    • 将Java源文件动态编译为.class文件

验证

  • 任务:确保加载的字节码是合法的,符合 JVM 规范。
  • 验证内容
    1. 文件格式验证
      • 检查字节码文件是否符合 JVM 规范(如魔数、版本号等)。
    2. 元数据验证
      • 检查类的元数据是否合法(如是否有父类、是否继承了 final 类等)。
    3. 字节码验证
      • 检查方法体中的字节码指令是否合法,是否会危害 JVM。
    4. 符号引用验证
      • 检查类、方法、字段的引用是否存在且可访问。

准备

  • 任务:为类的静态变量分配内存,并设置默认初始值。

  • 具体行为

    • 静态变量会被分配内存并初始化为零值(如 int 初始化为 0boolean 初始化为 false)。
    • 如果是常量(static final),则直接赋值为指定的值。
  • 示例:

java">static int a = 10;  // 准备阶段:a = 0
static final int b = 20;  // 准备阶段:b = 20

解析

  • 任务:将常量池中的符号引用转换为直接引用。
  • 符号引用:一组符号描述引用目标(如类名、方法名)。
  • 直接引用:指向目标在内存中的指针或偏移量。
  • 解析内容
    • 类或接口的解析。
    • 字段的解析。
    • 方法的解析。

初始化

  • 任务:执行类的静态初始化代码(静态代码块和静态变量赋值)。
  • 触发条件
    • 创建类的实例(new)。
    • 访问类的静态变量或静态方法。
    • 使用反射加载类(如 Class.forName())。
    • 初始化子类时,父类会先被初始化。
java">static int a = 10;  // 初始化阶段:a = 10
static {System.out.println("Static block executed");
}

类加载器

JVM 通过类加载器来加载类。Java 中有以下三类类加载器:

image-20250217224811133

启动类加载器(Bootstrap ClassLoader)

  • 职责:加载 JVM 核心类库(如 java.lang.*java.util.* 等)。
  • 实现:由 JVM 自身实现,通常是用 C/C++ 编写的。
  • 路径:加载 JAVA_HOME/lib 目录下的类。

扩展类加载器(Extension ClassLoader)

  • 职责:加载扩展类库(如 javax.* 等)。
  • 实现:由 sun.misc.Launcher$ExtClassLoader 实现。
  • 路径:加载 JAVA_HOME/lib/ext 目录下的类。

应用程序类加载器(Application ClassLoader)

  • 职责:加载用户类路径(ClassPath)下的类。
  • 实现:由 sun.misc.Launcher$AppClassLoader 实现。
  • 路径:加载 -classpath-cp 指定的类。

自定义类加载器(User-Defined ClassLoader)

  • 职责:用户可以通过继承 ClassLoader 类实现自定义类加载器。
  • 用途
    • 热部署:在不重启 JVM 的情况下重新加载类。
    • 模块化加载:加载特定模块的类。
    • 加密类加载:加载加密的字节码文件。

双亲委派模型

双亲委派模型是类加载器之间的协作机制。

工作原理

  1. 当一个类加载器需要加载类时,它首先会委托给父类加载器加载。
  2. 如果父类加载器无法加载,子类加载器才会尝试加载。
  3. 最终,如果所有父类加载器都无法加载,才会抛出 ClassNotFoundException

优点

  • 安全性:防止用户自定义的类替换核心类(如 java.lang.String)。
  • 避免重复加载:确保类只被加载一次。

打破双亲委派

  • 在某些场景下(如 SPI 服务加载、模块化加载),可能需要打破双亲委派模型。
  • 安全性:防止用户自定义的类替换核心类(如 java.lang.String)。
  • 避免重复加载:确保类只被加载一次。

打破双亲委派

  • 在某些场景下(如 SPI 服务加载、模块化加载),可能需要打破双亲委派模型。
  • 例如:Thread.currentThread().setContextClassLoader() 可以设置线程上下文类加载器。

http://www.ppmy.cn/devtools/160866.html

相关文章

DeepSeek助力:打造属于你的GPTs智能AI助手

文章目录 一、环境准备1.安装必要的工具和库2. 选择合适的开发语言 二、核心技术选型1. 选择适合的AI框架 三、功能实现1. 文本生成与对话交互2. 代码生成与自动补全3. 数据分析与报告生成 四、案例实战1. 搭建一个简单的聊天机器人2. 创建一个代码生成器 五、总结与展望1. 当前…

七星棋牌源码高阶技术指南:6端互通、200+子游戏玩法深度剖析与企业级搭建实战(完全开源)

在棋牌游戏行业高速发展的今天,如何构建一个具备高并发、强稳定性与多功能支持的棋牌游戏系统成为众多开发者和运营团队关注的焦点。七星棋牌全开源修复版源码 凭借其 六端互通、200子游戏玩法、多省区本地化支持,以及 乐豆系统、防沉迷、比赛场、AI智能…

C++笔记之标准库中的std::copy 和 std::assign 作用于 std::vector

C++笔记之标准库中的std::copy 和 std::assign 作用于 std::vector code review! 文章目录 C++笔记之标准库中的std::copy 和 std::assign 作用于 std::vector1. `std::copy`1.1.用法1.2.示例2.`std::vector::assign`2.1.用法2.2.示例3.区别总结4.支持assign的容器和不支持ass…

蓝桥杯 Java B 组 之堆的基础(优先队列实现 Top K 问题)

Day 6:堆的基础(优先队列实现 Top K 问题) 📖 一、什么是堆(Heap)? 堆(Heap) 是一种特殊的二叉树结构,满足: 最大堆(Max Heap&#…

网络安全钓鱼邮件测试 网络安全 钓鱼

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 如今,网络安全是一个备受关注的话题,“网络钓鱼”这个词也被广泛使用。 即使您对病毒、恶意软件或如何在线保护自己一无所知,您…

新数据结构(12)——代理

什么是代理 在进行操作时有时不希望用户直接接触到目标,这时需要使用代理让用户间接接触到目标 给目标对象提供一个代理对象,并且由代理对象控制着对目标对象的引用 图解: 代理的目的 控制访问:通过代理对象的方式间接的访问目…

DeepSeek动画视频全攻略:从架构到本地部署

DeepSeek 本身并不直接生成动画视频,而是通过与一系列先进的 AI 工具和传统软件协作,完成动画视频的制作任务。这一独特的架构模式,使得 DeepSeek 在动画视频创作领域发挥着不可或缺的辅助作用。其核心流程主要包括脚本生成、画面设计、视频合成与后期处理这几个关键环节。 …

yolo11s rknn无法detect的bugfix - step by step

1.缘起 上周四下班时,发现在宿主机环境工作良好的既有的pytorch模型,在通过.pt->.onnx->.rknn的转换后无法正常工作。周五下班时,怀疑疑点在两处: 版本匹配问题通道和参数传递问题。 周六,周日,周…