当前位置: 首页 > news >正文

7. JVM类加载器与双亲委派模型

1. 类加载器

类加载器是Java虚拟机(JVM)的重要组成部分,负责将.class文件(字节码文件)加载到JVM中,并转换为java.lang.Class类的实例。

Java中的类加载器类型

1. 启动类加载器(Bootstrap ClassLoader)

  • 由C++实现,是JVM的一部分

  • 负责加载Java核心类库(<JAVA_HOME>/jre/lib目录下的类)

  • 是其他所有类加载器的父加载器

  • 唯一没有父类的加载器

2. 扩展类加载器(Extension ClassLoader)

  • 由Java实现(sun.misc.Launcher$ExtClassLoader

  • 负责加载<JAVA_HOME>/jre/lib/ext目录下的类

  • 是应用类加载器的父加载器

3. 应用类加载器(Application ClassLoader/System ClassLoader)

  • 由Java实现(sun.misc.Launcher$AppClassLoader

  • 负责加载用户类路径(ClassPath)上的类库

  • 是程序中默认的类加载器

4. 自定义类加载器

开发者可以继承java.lang.ClassLoader类,实现自己的类加载器,用于特殊需求如:

  • 热部署

  • 代码加密

  • 从非标准位置加载类

在Java的不同版本中,<JAVA_HOME>/lib<JAVA_HOME>/jre/lib的关系有所变化:

Java 8 及之前版本根目录下包含 jre 目录。

Java 9 及之后版本根目录下不在包含 jre 目录,而是对其进行了合并统一。


2. 双亲委派模型

双亲委派模型是Java类加载器(ClassLoader)在加载类时遵循的一种工作机制,它是Java安全性和稳定性的重要保障。

核心原理

  1. 自底向上检查:当一个类加载器收到类加载请求时,它首先不会自己尝试加载,而是将这个请求委托给父类加载器去完成。

  2. 自顶向下尝试:只有当父类加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。

工作流程

  1. 当前类加载器首先检查请求的类是否已经被加载过

  2. 如果没有,则将加载任务委托给父类加载器

  3. 父类加载器同样遵循这个委托流程,直到启动类加载器(Bootstrap ClassLoader)

  4. 如果父类加载器无法完成加载(抛出ClassNotFoundException),则由当前类加载器尝试加载

  5. 如果当前类加载器也无法加载,则抛出ClassNotFoundException

优点

  1. 安全性:防止核心API被篡改(例如用户自定义的java.lang.String类不会被加载)

  2. 避免重复加载:同一个类只会被一个类加载器加载一次

  3. 稳定性:保证Java核心库的类型安全


3. 总结

3.1 什么是类加载器?

JVM只会运行二进制文件,类加载器的作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来。

3.2 类加载器有哪些? 

  • 启动类加载器(BootStrap ClassLoader):加载JAVA HOME/jre/lib目录下的库
  • 扩展类加载器(ExtClassLoader):主要加载JAVA HOME/jre/lib/ext目录中的类
  • 应用类加载器(AppClassLoader):用于加载classPath下的类
  • 自定义类加载器(CustomizeClassLoader):自定义类继承ClassLoader,实现自定义类加载规则。

3.3 什么是双亲委派模型?

加载某一个类,先委托上一级的加载器进行加载,如果上级加载器也有上级,则会继续向上委托,如果该类委托上级没有被加载,子加载器尝试加载该类。 

3.4 JVM为什么采用双亲委派机制?

  • 通过双亲委派机制可以避免某一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性。
  • 为了安全,保证类库API不会被修改

上一篇   下一篇

http://www.xdnf.cn/news/1109575.html

相关文章:

  • 关于两种网络攻击方式XSS和CSRF
  • 二分法寻找无序序列的峰值
  • [Token]Token merging for Vision Generation
  • 学python,PyCharm 和 VSCode哪个更好用?
  • ChatRex RexSeek RexThinker: 结合多模态大语言模型的目标检测模型构建
  • vue3+vit+vue-router路由,侧边栏菜单,面包屑导航设置层级结构
  • 商业机密保卫战:如何让离职员工带不走的客户资源?
  • 六年级数学知识边界总结思考-上册
  • Rust Web 全栈开发(五):使用 sqlx 连接 MySQL 数据库
  • 【赵渝强老师】国产数据库TiDB的代理路由:TiProxy
  • 服务器怎么跑Python项目?
  • 【代码随想录】刷题笔记——哈希表篇
  • MySQL 中图标字符存储问题探究:使用外挂法,毕业论文——仙盟创梦IDE
  • shiro550反序列化漏洞复现(附带docker源)
  • 【Docker基础】Dockerfile指令速览:基础常用指令详解
  • Leetcode百题斩-二分搜索
  • 使用langgraph 构建RAG 智能问答代理
  • springboot AOP面向切面编程
  • 连接池深度解析:原理、实现与最佳实践
  • Hap包引用的Hsp报签名错误怎么解决
  • 使用ESM3蛋白质语言模型进行快速大规模结构预测
  • 每日一SQL 【销售分析 III】
  • Python问题记录`No module named ‘matplotlib‘` 问题解决方案
  • 基于SEP3203微处理器的嵌入式最小硬件系统设计
  • 基于 Python 的数据分析技术综述
  • 剑指offer56_数组中唯一只出现一次的数字
  • 【MogDB】一种基于ctid分片并发查询以提升大表查询性能的方式
  • 【go】gopath、GO111MODULE=on作用
  • Javaweb- 11 MVC架构模式
  • JDK官方文档下载教程