类加载的基本流程

news/发布时间2024/9/20 5:43:29

⭐ 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:JavaEE
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖

类加载

  • 1. 加载
  • 2. 验证
  • 3. 准备
  • 4. 解析
  • 5. 初始化
  • 6. 双亲委派模型

对于⼀个类来说,它的⽣命周期是这样的:
在这里插入图片描述

1. 加载

“加载”(Loading)阶段是整个“类加载”(Class Loading)过程中的⼀个阶段,它和类加载
Class Loading 是不同的,⼀个是加载 Loading 另⼀个是类加载 Class Loading。

在加载 Loading 阶段,Java虚拟机需要完成以下三件事情:

  1. 通过⼀个类的“全限定名”来获取定义此类的⼆进制字节流
  2. 将这个字节流所代表的静态存储结构转化为⽅法区的运⾏时数据结构
  3. 在内存中⽣成⼀个代表这个类的java.lang.Class对象,作为⽅法区这个类的各种数据的访问⼊⼝

也就是找到.class文件,打开文件,读取文件内容。
当代码中给定某个类的“全限定类名”,比如:java.lang.String,java.util.ArrayList,然后jvm就会根据这个类名在一些指定的目录范围内查找。

2. 验证

验证是连接阶段的第⼀步,这⼀阶段的⽬的是确保Class⽂件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信息被当作代码运⾏后不会危害虚拟机⾃⾝的安全。

验证选项:

  • ⽂件格式验证
  • 字节码验证
  • 符号引⽤验证

3. 准备

准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段。
⽐如此时有这样⼀⾏代码:

public static int value = 123;

它是初始化 value 的 int 值为 0,⽽⾮ 123

只是分配内存空间,还没有初始化。此时这个空间上的内存的数值,就是全0的。

4. 解析

针对类对象中包含的字符串常量进行处理,进行一些初始化操作。也就是将常量池内的符号引用替换为直接引用

比如:final String s="abc",当字符串常量 s 在编译之后,也会进入 .class 文件,同时在 .class 文件的二进制指令中,也会有一个 s 这样的引用被创建出来。我们知道引用里本质上保存的是一个变量的地址,但在.class文件中,不涉及到内存地址,因此在.class 文件中,s的初始化语句,就会先被设置成一个“文件的偏移量”,通过偏移量,就能找到 “abc” 这个字符串所在的位置,当我们这个类真正被加载到内存中的时候,再把这个偏移量替换回真正的内存地址。

5. 初始化

初始化阶段,Java 虚拟机真正开始执⾏类中编写的 Java 程序代码,将主导权移交给应⽤程序。针对类对象进行初始化,初始化阶段就是执⾏类构造器⽅法的过程。
比如:把类对象中需要的各个属性都设置好;初始化好static成员;执行静态代码块;还可能需要加载一下父类等等。

6. 双亲委派模型

双亲委派模型属于类加载中第一个步骤“加载”过程中的一个环节。它的作用就是根据全限定名找到 .class文件。

解释:类加载器是JVM中的一个模块,而JVM内置了三个类加载器。
当⼀个类加载器收到了类加载的请求,它⾸先不会⾃⼰去尝试加载这个类,⽽是把这个请求委派给⽗类加载器去完成,每⼀个层次的类加载器都是如此,因此所有的加载请求最 终都应该传送到最顶层的启动类加载器中,只有当⽗加载器反馈⾃⼰⽆ 法完成这个加载请求(它的搜索范围中没有找到所需的类)时,⼦加载器才会尝试⾃⼰去完成加载。

在这里插入图片描述
上图类加载的过程(找.class 文件的过程)

  1. 给定一个类的全限定类名,形如java.lang.String
  2. 从Application ClassLoader作为入口,开始执行查找的逻辑
  3. Application ClassLoader,不会立即去扫描自己负责的目录(负责的是搜索项目当前目录和第三方库对应目录)而是把查找的任务,交给它的父亲,Extension Classloader
  4. Extension ClassLoader也不会立即扫描自己负责的目录(负责的是 JDK中一些扩展的库,对应的目录)而是把查找的任务,交给它的父亲BootStrap ClassLoader
  5. BootStrap Classloader,也不想立即扫描自己负责的目录(负责的是标准库的目录), 也想把任务交给它的父亲,结果发现自己没有父亲!因此BootStrap ClassLoader 只能亲自负责扫描标准库的目录
  6. 没有扫描到,就会回到Extension ClassLoader。Extension ClassLoader就会扫描负责的扩展库的目录。如果找到,就执行后续的类加载操作,此时查找过程结束;如果没找到,还是把任务交给孩子来执行
  7. 没有扫描到,就会回到Application ClassLoader。Application ClassLoader就会负责扫描当前项目和第方库的目录。如果找到,就执行后续的类加载操作。如果没找到,就会抛出一个ClassNotFoundException

优点:

  • 避免重复加载类:⽐如 A 类和 B 类都有⼀个⽗类 C 类,那么当 A 启动时就会将 C 类加载起来,那么在 B 类进⾏加载时就不需要在重复加载 C 类了。
  • 安全性:使⽤双亲委派模型也可以保证了 Java 的核⼼ API 不被篡改,如果没有使⽤双亲委派模
    型,⽽是每个类加载器加载⾃⼰的话就会出现⼀些问题,⽐如我们编写⼀个称为 java.lang.Object
    类的话,那么程序运⾏的时候,系统就会出现多个不同的 Object 类,⽽有些 Object 类⼜是⽤⼾⾃⼰提供的因此安全性就不能得到保证了。

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

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

AI大预言模型——ChatGPT与AI绘图及论文高效写作

原文链接:AI大预言模型——ChatGPT与AI绘图及论文高效写作 2023年随着OpenAI开发者大会的召开,最重磅更新当属GPTs,多模态API,未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义,不亚于互联网…

JVM运行时数据区——虚拟机栈

文章目录 1、虚拟机栈概述1.1、StackOverflowError1.2、OOM异常 2、栈的存储单位3、局部变量表3.1、局部变量表简介3.2、Slot 4、操作数栈5、栈顶缓存技术6、动态链接7、方法的调用7.1、方法调用的分类7.2、虚方法与非虚方法7.3、关于invokedynamic指令7.4、方法重写的本质7.5、…

【Django】执行查询—跨关系查询中的跨多值关联问题

跨多值查询 跨越 ManyToManyField 或反查 ForeignKey (例如从 Blog 到 Entry )时,对多个属性进行过滤会产生这样的问题:是否要求每个属性都在同一个相关对象中重合。 filter() 先看filter(),通过一个例子看&#xf…

C语言 vs Rust应该学习哪个?

C语言 vs Rust应该学习哪个? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「C语言的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!&am…

Qt应用软件【测试篇】vargrid内存检查工具

文章目录 vargrid介绍vargrid官网vargrid安装常用命令Valgrind的主要命令vargrid介绍 Valgrind是一个用于构建动态分析工具的框架,能自动检测许多内存管理和线程错误,并详细分析程序性能。Valgrind发行版包括七个成熟工具:内存错误检测器、两个线程错误检测器、缓存和分支预…

socket套接字

前言 两个应用程序如果需要进行通讯最基本的一个前提就是能够唯一的标示一个进程,我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号可以唯一标示主机的一个进程,这样我们可以利用ip地址+协议+端口号唯一标示…

工厂生产效率如何提升?这8个重点你不得不看!

企业的竞争本质上就是效率与成本的竞争(当然是保证产品质量的前提下),如何持续不断地提高生产效率是企业永续发展的关键问题,提高生产效率也是降低制造成本的根本途径。 当然,我们必须严格根据工艺标准来操作&#xf…

docker存储驱动

目录 一、写时复制和用时分配 二、联合文件系统 2.1、aufs ​编辑 2.2、分层的问题 2.3、overlay 2.4 文件系统区别 三、容器跑httpd案例 3.1、案例1:端口映射 3.2、案例2:制作httpd应用镜像 3.3、案例3:docker数据卷挂载 3.4、案…

探索数据结构:解锁计算世界的密码

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:数据结构与算法 贝蒂的主页:Betty‘s blog 前言 随着应用程序变得越来越复杂和数据越来越丰富,几百万、…

继承-学习2

this关键字:指向调用该方法的对象,一般我们是在当前类中使用this关键字,所以我们常说代表本类对象的引用 super关键字:代表父类存储空间的标识(可看作父类对象的引用) 父类: package ven;public class Fu {//父类成员…

细嗦MySQL三大日志

文章目录 三大日志:binlog(归档日志)、redo log(重做日志)、undo log(回滚日志)redo log刷盘机制日志文件组 binlog记录格式写入机制 两阶段提交undo log提供回滚操作提供MVCC(多版本…

SQL-Labs靶场“46-50”关通关教程

君衍. 一、四十六关 ORDER BY数字型注入1、源码分析2、rand()盲注3、if语句盲注4、时间盲注5、报错注入6、Limit注入 二、四十七关 ORDER BY单引号报错注入1、源码分析2、报错注入3、时间盲注 三、四十八关 ODRER BY数字型盲注1、源码分析2、rand()盲注3、if语句盲注4、时间盲注…

Java进阶(锁)——锁的升级,synchronized与lock锁区别

目录 引出Java中锁升级synchronized与lock锁区别 缓存三兄弟:缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 Java进阶(锁)——锁的升级,synchronized与lock锁区别 Java中锁升级 看一段代码: public class…

Windows 10 合并磁盘分区 (G and H)

Windows 10 合并磁盘分区 [G and H] 1. 设备和驱动器2. 计算机 -> 管理 -> 存储 -> 磁盘管理3. 删除卷4. 新建简单卷5. 设备和驱动器References 1. 设备和驱动器 2. 计算机 -> 管理 -> 存储 -> 磁盘管理 3. 删除卷 H: -> right-click -> 删除卷 H: 变…

消息中间件篇之RabbitMQ-消息不丢失

一、生产者确认机制 RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。消息发送到MQ以后,会返回一个结果给发送者,表示消息是否处理成功。 当消息没有到交换机就失败了,就会返回publish-confirm。当消息没有到达MQ时&…

10分钟SkyWalking与SpringBoot融合并整合到Linux中

1.依赖配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.2.0.RELEASE</version></dependency><dependency><groupId>org.springframe…

【C++】二叉搜索树

目录 介绍&#xff1a; 一&#xff0c;二叉搜索树操作 1&#xff0c;搜索二叉树的简单封装 2&#xff0c;二叉搜索树的查找 3&#xff0c;二叉搜索树的插入 4&#xff0c;二叉搜索树的删除 二&#xff0c;递归实现二叉搜索树的操作 1&#xff0c;二叉搜索树的递归查找 …

AI也来打掼蛋,难道人工智能也能当领导?

引言&#xff1a;探索AI在复杂卡牌游戏中的决策能力 在人工智能&#xff08;AI&#xff09;的研究领域中&#xff0c;游戏被视为现实世界的简化模型&#xff0c;常常是研究的首选平台。这些研究主要关注游戏代理的决策过程。例如&#xff0c;中国的传统卡牌游戏“掼蛋”&#…

新闻网站封锁AI爬虫 AI与新闻媒体博弈继续

随着ChatGPT等新兴AI模型的兴起&#xff0c;它们所依赖的网络爬虫正面临来自全球主流新闻网站的大规模封锁。Richard Fletcher博士团队对十个国家主流新闻网站的统计发现&#xff0c;到2023年底&#xff0c;48%的网站屏蔽了OpenAI的爬虫&#xff0c;24%屏蔽了Google的爬虫。那么…

【IEEEE会议征稿】第六届下一代数据驱动网络国际学术会议(NGDN 2024)

第六届下一代数据驱动网络国际学术会议&#xff08;NGDN 2024&#xff09; The Sixth International Conference on Next Generation Data-driven Networks 基于前几届在英国埃克塞特 (ISPA 2020) 、中国沈阳 (TrustCom 2021) 和中国武汉(IEEETrustCom-2022)成功举办的经验&a…
推荐文章