JVM(类加载机制)

类加载就是 .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.mfbz.cn/a/430107.html

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

相关文章

[数据集][目标检测]鸡蛋破蛋数据集VOC+YOLO格式792张2类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):792 标注数量(xml文件个数):792 标注数量(txt文件个数):792 标注类别…

OpenDDS 在 Windows 上的编译环境部署指南

目录 1、OpenDDS2、编译OpenDDS2.1、准备工作2.2、配置环境变量2.3、编译-TAO_IDL_ACE2.4、编译-TAO_ACE2.5、编译-ACE2.7、生成OpenDDS的解决方案2.8、编译-DDS_no_test2.9、编译-DDS 1、OpenDDS OpenDDS是使用C语言针对OMG数据分发服务(DDS)的一种开源实现。由OCI公司设计和…

07. Nginx进阶-Nginx负载均衡

简介 负载均衡 什么是负载均衡? 负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行。 Nginx负载均衡 什么是Nginx负载均衡? Nginx负载均衡可以大…

Kubernetes 二进制部署 《easzlab / kubeasz项目部署》- 00-规划集群和配置介绍(二)

Kubernetes 二进制部署 - easzlab / kubeasz项目部署 00-规划集群和配置介绍1.首先创建集群配置实例2. 修改配置文件 在前一章,我们部署了一些基本环境,服务器,接下来,我们开始部署k8s相关组件 server list 类型IP主机名VIPgitl…

STM32 TIM编码器接口

单片机学习! 目录 文章目录 前言 一、编码器接口简介 1.1 编码器接口作用 1.2 编码器接口工作流程 1.3 编码器接口资源分布 1.4 编码器接口输入引脚 二、正交编码器 2.1 正交编码器功能 2.2 引脚作用 2.3 如何测量方向 2.4 正交信号优势 2.5 执行逻辑 三、编码器定时…

WebGIS开发0基础必看教程:地图瓦片在Canvas上的拼接显示

1.前言 在之前的五个章节中,我们在第一章节里介绍了WebGIS的基本框架和技术,第二章节里介绍了什么是瓦片行列号以及计算它的原因,第三章节里介绍了如何通过地理范围计算出这个范围内瓦片的行列号,第四和第五章节里介绍了在得到瓦…

如何让 JOIN 跑得更快?

JOIN 一直是数据库性能优化的老大难问题,本来挺快的查询,一旦涉及了几个 JOIN,性能就会陡降。而且,参与 JOIN 的表越大越多,性能就越难提上来。 其实,让 JOIN 跑得快的关键是要对 JOIN 分类,分…

C++max函数的使用案例20个

文章目录 1. **基本用法:**2. **比较浮点数:**3. **比较字符串:**4. **使用自定义比较函数:**5. **比较容器中的元素:**6. **使用std::initializer_list:**7. **变长参数版本(C11及以上&#xf…

c++的队列的用法

基本介绍 c的队列就是std::queue。 需要包含的头文件&#xff1a; #include<queue>queue就是先进先出队列 queue,就是队列&#xff0c;队列是一种容器适配器&#xff0c;专门设计用于在FIFO上下文中操作(先进先出)&#xff0c;其中将元素插入容器的一端并从另一端提…

广东Lenovo SR588服务器维修升级硬盘内存

本案例描述了对联想SR588服务器进行硬件升级的过程&#xff0c;包括更换固态硬盘作为系统盘&#xff0c;以及增加内存容量至128GB。升级后&#xff0c;服务器性能得到显著提升&#xff0c;同时通过重新配置RAID阵列和操作系统的重新安装&#xff0c;确保了系统的稳定性和数据的…

华为路由器 三层交换实现vlan通信 实验(附ensp实验源文件)

一、目标 通过三层交换实现vlan通信 二、网络配置 2.1 交换机1&#xff08;LSW1&#xff09;配置 # 创建两个vlan vlan 10 vlan 20# 配置g0/0/1端口 port link-type access port default vlan 10# 配置g0/0/2端口 port link-type access port default vlan 20# 配置g0/0/3端口…

STM32F1 - SPI读写Flash

Serial peripheral interface 1> 实验概述2> SPI硬件框图初始化程序 3> STM32的SPI通信时序3.1> 时序图3.2> 文字描述3.3> 注意事项3.4> 流程图表示3.5> 程序表示接收程序&#xff1a;发送程序&#xff1a; 4> SPI的4种模式5> W25Q128存储结构块…

开发知识点-Python-爬虫

爬虫 scrapybeautifulsoupfind_all find祖先/父节点兄弟节点nextpreviousCSS选择器属性值 attrsselect 后 class 正则使用字符串来描述、匹配一系列符合某个规则的字符串组成元字符使用grep匹配正则组与捕获断言与标记条件匹配正则表达式的标志 特定中文 匹配 scrapy scrapy内…

ssm+springboot音乐播放器网站mybatis+jsp

测试流程 &#xff08;1&#xff09; 登录系统、填写用户名、密码选择角色&#xff0c;主要内容&#xff1a;进行权限控制。 &#xff08;2&#xff09; 用户查看音乐信息、音乐资讯功能&#xff0c;主要是测试系统实用性、方便性。 &#xff08;3&#xff09; 信息修…

B084-SpringCloud-Zuul Config

目录 zuul系统架构和zuul的作用zuul网关实现配置映射路径过滤器 Config概述云端管理本地配置 zuul zuul是分布式和集群后前端统一访问入口 系统架构和zuul的作用 zuul把自己注册进eureka&#xff0c;然后可通过前端传来的服务名发现和访问对应的服务集群 为了预防zuul单点故…

在Java中处理JSON数据:Jackson与Gson库比较

引言 JSON&#xff0c;作为一种轻量级的数据交换格式&#xff0c;因其易于人阅读和编写&#xff0c;同时也易于机器解析和生成&#xff0c;而被广泛应用于网络通信和配置文件中。在Java中&#xff0c;有两个强大的工具帮助咱们处理JSON数据——Jackson和Gson。这两个库各有千秋…

Conda 快速入门,轻松拿捏 Python

一、简介 Conda 是一个开源的软件包管理系统和环境管理系统&#xff0c;用于安装多个版本的软件包及其依赖关系&#xff0c;并在它们之间轻松切换。Conda 是为 Python 程序创建的&#xff0c;适用于 Linux&#xff0c;OS X 和Windows&#xff0c;也可以打包和分发其他软件&…

teknoparrot命令行启动游戏

官方github cd 到teknoparrot解压目录 cd /d E:\mn\TeknoParrot2_cp1\GameProfiles启动游戏 TeknoParrotUi.exe --profile游戏配置文件游戏配置文件位置/UserProfiles,如果UserProfiles文件夹里没有那就在/GameProfiles,在配置文件里将游戏路径加入之间,或者打开模拟器设置 …

SpringCloud Alibaba 学习

一&#xff1a;SpringCloud Alibaba介绍 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服 务的必需组件&#xff0c;方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。 依托 Spring Cloud Alibaba&…

mybatis不重复列插入例子详细说明

之前有做过不重复列插入的需求&#xff0c;当时是 在插入时判断 对应的列在数据库中有没有对应的数据 有则返回false 无则插入&#xff0c;但是这加大了数据库的查询负担 也增加了插入的时间&#xff0c;故今天研究一下 使用sql来简化了这一点 使用的知识点是 daul表 insert i…
最新文章