JVM(类加载机制)

news/2024/5/15 8:40:08

类加载就是 .class 文件, 从文件(硬盘) 被加载到内存(元数据区)中的过程


类加载的过程

在这里插入图片描述

加载: 找 .class 文件的过程, 打开文件, 读文件, 把文件读到内存中

验证: 检查 .class 文件的格式是否正确

  • .class 是一个二进制文件, 其格式有严格的说明

准备: 给类对象分配内存空间 (先在元数据区占个位置), 也会使静态成员被设置成 0 值

解析: 初始化字符串常量, 把符号引用转换为直接引用

  • 字符串常量,有一块内存空间存放其实际内容, 还有一个引用,来保存这块内存空间的起始地址
  • 在类加载之前,字符串常量处在 .class 文件中, 此时这个 引用 记录的并非是字符串常量的真正地址, 而是它在文件中的 “偏移量” (或者说是占位符)
  • 类加载之后, 才真正把这个字符串常量给放到内存中, 此时才有 “内存地址”,该引用才能被真正赋值成指定的内存地址

初始化: 调用构造方法, 进行成员初始化, 执行代码块, 静态代码块, 加载父类 …

顺便看一下类的生命周期

在这里插入图片描述


一个类加载的时机(一个类何时会被加载)

JVM 采用的是懒汉模式

1.构造类的实例
2.调用该类的静态方法 / 使用静态属性
3.加载子类的时候, 会先加载其父类

即用到了, 才加载, 加载过后, 后续使用不必重复加载


双亲委派模型

上述类加载过程中有个环节 ---- 加载 : 找到 .class 文件, 并读取到内存中
双亲委派模型,描述的就是该过程

JVM 提供了三个类加载器
BootstapClassLoader : 负责加载 标准库 中的类, Java 规范要求提供的类(即所有 JVM 都会提供的)
ExtensionClassLoader : 负责加载 JVM 拓展类 中的类, 规范之外, JVM 厂商 / 组织提供的额外的功能
ApplicationClassLoader : 负责加载 用户提供的第三方库 / 用户项目代码 中的类

上述三个类加载器存在 “父子关系”, 即每个类加载器中有一个 parent 属性指向自己的 父 类加载器

上述类加载器如何配合工作?(双亲委派模型的流程)

简单版本:
如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父
类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最 终都应该传送到最顶层的启
动类加载器中,只有当父加载器反馈自己无 法完成这个加载请求(它的搜索范围中没有找到所需的类)
时,子加载器才会尝试自己去完成加载。

详细版本:
当加载一个类的时候, 先从 ApplicationClassLoader 开始
但是 ApplicationClassLoader 不会直接加载, 而是会把任务交给自己的父亲,让父亲去完成
于是 ExtensionClassLoader 就去加载了, 但是 ExtensionClassLoader 也不是直接加载, 而是再委托给自己的父亲去加载
现在 BootstrapClassLoader 就要去加载了, 在此之前, BootstrapClassLoader 也会先委派给自己的父亲, 此时会发现, 自己的父亲是 null
即 BootstrapClassLoader 并没有父亲

  • 没有父亲或者父亲加载完了,没有找到类, 这两种情况下才会由自己加载

此时 BootstrapClassLoader 会加载该类, 即搜索自己负责的标准库目录里的相关类, 如果找到, 就加载, 找不到,则由子类加载器进行加载
ExtensionClassLoader 搜索拓展库相关目录, 如果找到就加载, 找不到就由子类加载器进行加载
ApplicationClassLoader 搜索用户项目相关目录, 如果找到就加载, 找不到就由子类加载器进行加载 (由于 ApplicationClassLoader 没有子加载器, 会抛出异常 ---- 类找不到)

双亲委派模型的目的

保证 Bootstrap 能够先加载类, Appcation 能够后加载类
放在当用户自定义的类和标准库中类同名时, 能够优先使用标准库中的类(防止不必要的 bug)

双亲委派模型的优点(其实就是上面目的的另一种说法)

  1. 避免重复加载类
  2. 安全性: 使用双亲委派模型保证 Java 的核心 API 不被篡改

破坏双亲委派模型

很好的一个示例是 JDBC
其中 Driver 接口的实现类是由 子类加载器加载的 (我自己包里的类肯定是要用的, 如果遵循双亲委派模型, 那我不是白写了 [用不到] )

综上, 是否遵循双亲委派模型可以根据需求具体修改

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.cpky.cn/p/10217.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

3分钟开通GPT-4

AI从前年12月份到现在已经伴随我们一年多了,还有很多小伙伴不会开通,其实开通很简单,环境需要自己搞定,升级的话就需要一张visa卡,办理visa卡就可以直接升级chatgptPLSU 一、虚拟卡支付 这种方式的优点是操作简单&…

制作一个简单的HTML个人网页

制作一个简单的HTML个人网页 1.1 硬件1.1.1 一台电脑1.1.2 配置要求 1.2 系统1.3 软件 二、制作一个简单的HTML个人网页1.创建一个HTML网页1.1 新建文本文档1.2 另存文本文档1.3 命名为index.html 2.编写HTML代码2.1 打开HTML2.2 复制HTML代码2.3 粘贴HTML代码2.4 保存HTML 3.预…

MySQL--优化(索引--聚簇和非聚簇索引)

MySQL–优化(索引–聚簇和非聚簇索引) 定位慢查询SQL执行计划索引 存储引擎索引底层数据结构聚簇和非聚簇索引索引创建原则索引失效场景 SQL优化经验 一、聚簇索引 聚簇索引:将数据存储与索引放到了一块,索引结构的叶子节点保存…

【洛谷 P8682】[蓝桥杯 2019 省 B] 等差数列 题解(数学+排序+辗转相除法)

[蓝桥杯 2019 省 B] 等差数列 题目描述 数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列,只记得其中 N N N 个整数。 现在给出这 N N N 个整数,小明想知道包含这 N N N 个整数的最短的等差数列有几项? 输…

java集合类常用的方法介绍

在 Java 中,集合(Collections)是用于存储多个元素的容器。Java Collections Framework 提供了丰富的集合类,用于满足不同的数据存储需求。以下是一些常用的 Java 集合类及其常用方法,以及简单的例子来说明它们的用法。…

【每日一题】LeetCode——链表的中间结点

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有…