类加载机制和双亲委派机制

news2024/9/22 23:38:58

文章目录

📕我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文创造者、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。🌎跑过十五公里、徒步爬过衡山、🔥有过三个月减肥20斤的经历、是个喜欢躺平的狠人。

📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、Spring MVC、SpringCould、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RockerMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。🎥有从0到1的高并发项目经验,利用弹性伸缩、负载均衡、报警任务、自启动脚本,最高压测过200台机器,有着丰富的项目调优经验。

以梦为马,不负韶华

希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!

  • 💂 博客主页: 我是廖志伟
  • 👉开源项目:java_wxid
  • 🌥 哔哩哔哩:我是廖志伟
  • 🎏个人社区:幕后大佬
  • 🔖个人微信号SeniorRD

📥博主的人生感悟和目标

探寻内心世界,博主分享人生感悟与未来目标

  • 🍋程序开发这条路不能停,停下来容易被淘汰掉,吃不了自律的苦,就要受平庸的罪,持续的能力才能带来持续的自信。我本是是一个很普通程序员,放在人堆里,除了与生俱来的盛世美颜,就剩180的大高个了,就是我这样的一个人,默默写博文也有好多年了。
  • 📺有句老话说的好,牛逼之前都是傻逼式的坚持,希望自己可以通过大量的作品、时间的积累、个人魅力、运气、时机,可以打造属于自己的技术影响力。
  • 💥内心起伏不定,我时而激动,时而沉思。我希望自己能成为一个综合性人才,具备技术、业务和管理方面的精湛技能。我想成为产品架构路线的总设计师,团队的指挥者,技术团队的中流砥柱,企业战略和资本规划的实战专家。
  • 🎉这个目标的实现需要不懈的努力和持续的成长,但我必须努力追求。因为我知道,只有成为这样的人才,我才能在职业生涯中不断前进并为企业的发展带来真正的价值。在这个不断变化的时代,我必须随时准备好迎接挑战,不断学习和探索新的领域,才能不断地向前推进。我坚信,只要我不断努力,我一定会达到自己的目标。

CSDN

📙经过多年在CSDN创作上千篇文章的经验积累,我已经拥有了不错的写作技巧。同时,我还与清华大学出版社签下了四本书籍的合约,并将陆续在明年出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码–沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!

🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。

💡在这个美好的时刻,本人不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。


🍊 类加载机制和双亲委派机制

第一步,加载,一个Java源文件进行编译之后,成为一个class字节码文件存储在磁盘上面,这个时候jvm需要读取这个字节码文件,通过通过IO流读取字节码文件,这一步就是加载。

类加载器将.class文件加载到JVM,首先是看当前类是不是使用自定义加载类加载的,如果不是,就委派应用类加载器加载,如果有加载过这个class文件,那就不用再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类的扩展类加载器同理也会先检查自己是不是已经加载过,如果没有再往上,看看启动类加载器。到启动类加载器,已经没有父加载器了,这时候开始考虑自己是否能加载了,如果自己加载不了,就会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException找不到类异常,这就是所谓的双亲委派机制。
这种机制可以避免,同路径下的同文件名的类,比如,自己写了一个java.lang.obejct,这个类和jdk里面的object路径相同,文件名也一样,这个时候,如果不使用双亲委派机制的话,就会出现不知道使用哪个类的情况,而使用了双亲委派机制,它就委派给父类加载器就找这个文件是不是被加载过,从而避免了上面这种情况的发生。
在这里插入图片描述

第二步,验证,JVM读到文件也不是直接运行,还需要校验加载进来的字节码文件是不是符合JVM规范

验证的第一步就是文件的格式验证,验证class文件里面的魔数和主次版本号,发现它是一个jvm可以支持的class文件并且它的主次版本号符合兼容性要求,所以验证通过。

第三步,加载,它会将class文件这个二进制静态文件转化到方法区里面,转化为方法区的时候,会有一个结构的调整,将静态的存储文件转化为运行时数据区,这个转化等于说又回到了加载。

接着到了方法区的运行时数据区以后,在java堆内存里面生成一个当前类的class对象,作为方法区里面这个类,被各种访问的一个入口。比如说object类,它是所有类都继承它,访问它,所以它也需要一个被各种类访问的入口。object类先加载,加载完成之后,它经过这一系列的操作,把自己java.lang.object放到这个堆里面,要让其他的类进行访问,这个也是加载。

第四步,继续验证,接着元数据验证,它会对字节码描述的信息进行语义分析,比如:这个类是不是有父类,是不是实现了父类的抽象方法,是不是重写了父类的final方法,是不是继承了被final修饰的类等等。

然后字节码验证,通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的,比如:操作数栈的数据类型与指令代码序列是不是可以配合工作,方法中的类型转换是不是有效等等。

最后符号引用验证:确保解析动作可以正确执行,比如说:通过符号引用是不是可以找到对应的类和方法,符号引用中类、属性、方法的访问性是不是能被当前类访问等,验证完成之后,需要做准备。

第五步,分配内存空间,准备就是给类的静态变量分配内存,并赋予默认值。我们的类里,可能会包含一些静态变量, 比如说public static int a = 12; 得给a这个变量分配个默认值 0,再比如public static User user = new User(); 给 static的变量User分配内存,并赋默认值null。如果是final修饰的常量,就不需要给默认值了,直接赋值就可以了。

第六步,解析,解析就是将符号引用变为直接引用,该阶段会把一些静态方法替换为指向数据储存在内存中的指针或者句柄,也就是所谓的直接引用,这个就是静态链接过程,是在初始化之前完成。有静态链接就有动态链接,动态链接是在程序运行期间完成将符号引用替换为直接引用,比如静态方法里面有个方法,在运行的时候,方法是存放在常量池中的符号,运行到这个符号,就是找这个符号对应的方法区,因为代码的指令是加载到方法区里面去的,最后把方法对应代码的地址放到栈帧中的动态链接里。

  • 编译器中的解析阶段其目的是将符号引用(如变量、函数等名字)转换成直接引用(如指向内存中的地址),从而使程序能够正确地执行。
  • 直接引用是指程序中直接使用的方法或数据在内存中对应的地址。在程序编译期间,编译器将所有的方法和数据按照一定的规则映射到内存中的不同位置,生成可执行文件。在程序运行期间,程序通过直接引用来访问这些方法和数据,直接引用一般是一个绝对地址或偏移量。因此,在程序运行时,操作系统需要将程序中的符号引用转换成直接引用,以正确地访问方法和数据。
  • 符号引用是指程序中使用的方法或数据的标识符,不是直接的内存地址。在编译期间,编译器不能确定符号引用对应的具体地址,因为这些方法和数据在运行时可能会被加载到不同的内存地址上。因此,在编译期间,编译器将符号引用记录在符号表中,并在链接期间将符号引用解析为直接引用。在操作系统加载程序之前,链接器会根据符号表中的信息,找到并解析程序中所有的符号引用,将它们转换为直接引用。
  • 静态链接是指将程序中所有需要用到的代码和数据在编译时就全部链接成一个可执行文件的过程。在静态链接过程中,编译器会将静态库中的函数和变量复制到可执行文件中,形成一个完整的可执行文件。在程序运行时,所有的代码和数据都存在于内存中,程序不需要再依赖外部库文件或动态链接库。静态链接的缺点是可执行文件较大,不易于维护和更新。
  • 动态链接是一个程序运行时(运行期间)连接目标文件模块的过程,将需要的代码添加到进程的地址空间中,并将不同的模块组合在一起,使它们能够相互调用。在动态链接的过程中,程序中的符号引用被动态解析为直接引用,这样程序才能正确地访问方法和数据。动态链接的好处是减小了程序的大小,同时也方便了程序的更新和维护。常见的动态链接库(DLL)就是使用动态链接方式加载的。
  • 在静态链接过程中,一些静态方法会被替换成直接引用,这个过程在程序初始化之前完成。动态链接是在程序运行期间完成,它会将符号引用替换成直接引用,使程序能够正确地访问方法和数据。具体来说,动态链接会将符号引用对应的方法的代码地址放到栈帧中的动态链接里,从而实现符号引用到直接引用的转换。

第七步,初始化了,初始化就是对类的静态变量初始化为指定的值并且会执行静态代码块。比如准备阶段的public static final int a = 12;这个变量,就是准备阶段给static变量a赋了默认值0,这一步就该把12赋值给它了。还有static的User public static User user = new User(); 把User进行实例化。

第八步,就是使用和卸载了,到此整个加载流程就走完了。
CSDN

🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

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

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

相关文章

winodos下使用VS2022编译eclipse-paho.mqtt.c并演示简单使用的 demo

本文演示C语言如何使用eclipse-paho.mqtt.c库,包含自行编译库的步骤或者下载编译好的文件。 1.下载paho.mqtt.c库源码(zip 文件) 到官网选择C版本的paho源码进行下载 Eclipse Paho | The Eclipse Foundation 或者到下述连接下载 Releases ec…

docker在java项目中打成tar包

docker在java项目中打成tar包 1、首先安装一个docker desktop 2、mvn install项目后,建立一个自己的dockerfile 这里我以我的代码举例,from 镜像,这里你也能打包好一个镜像的基础上,from打好的镜像,这里我们用openj…

【C语言初阶】 一文详解分支语句 if

🎬 鸽芷咕:个人主页 🔥 个人专栏:《速学C语言》《数据结构篇》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言结构化程序设计的三种基本结构💬 分支语句 (选择结构)📑 if 语句…

平衡二叉树(AVL)

平衡二叉树 基本介绍 左旋转调整成平衡二叉树 右旋转调整成平衡二叉树 双旋转调整成平衡二叉树 上述三种旋转方式的代码实现 class Node:"""创建 Node 节点"""value: int 0left Noneright Nonedef __init__(self, value: int):self.value …

HFS 快速搭建 http 服务器

HFS 是一个轻量级的HTTP 服务工具,3.0版本前进提供Windows平台安装包,3.0版本开提供Linux和macOS平台的安装包。 HFS更适合在局域网环境中搭建文件共享服务或者安装配置源服务器。 甲 非守护进程的方式运行 HFS (Ubuntu 22.04) 一…

c语言进制的转换2进制转换16进制

c语言进制的转换2进制转换16进制 c语言的进制的转换 c语言进制的转换2进制转换16进制一、16进制的介绍二、八四二一法则2进制转换16进制的方法 一、16进制的介绍 十六进制: 十六进制逢十六进一,所有的数组是0到9和A到F组成,其中A代表10&…

【C++基础入门】42.C++中同名覆盖引发的问题

一、父子间的赋值兼容 子类对象可以当作父类对象使用&#xff08;兼容性) 子类对象可以直接赋值给父类对象子类对象可以直接赋值给父类对象父类指针可以直接指向子类对象父类引用可以直接引用子类对象 下面看一个子类对象兼容性的代码&#xff1a; #include <iostream>…

EasyConnect

EasyConnect 简介下载安装 简介 EasyConnect 是一种远程连接解决方案&#xff0c;它允许用户通过互联网远程访问和控制其设备和资源。 下载 链接: https://pan.baidu.com/s/1JvejSUA8Tma91FOUv6Gswg 提取码: 3fb5 安装

7-4、S加减速转动实现【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;本节介绍实现步进电机S曲线运动的代码 一、目标功能 实现步进电机转动总角度720&#xff0c;其中加减速各90 加速段&#xff1a;加速类型&#xff1a;S曲线   加速角度&#xff1a;角度为90   起步速度&#xff1a;30RPM&#xff0c;   终止速度&#x…

现在java和大数据选什么?

现在java和大数据选什么&#xff1f; 到底是选择大数据还是JAVA&#xff1f;”相信这个问题困惑着许多转行待定人士和高校专业待选的学生。 在普通人眼里可能会觉得这两个专业或者行业没啥区别&#xff0c;都是IT里的&#xff0c;能有啥大不同。这是第一层。最近很多小伙伴找我…

Linux系统中让$前面显示完整的路径

目录 ■修改前效果 ■修改后效果 ■修改方法 ■修改前效果 ■修改后效果 ■修改方法 step1.找到当前用户下面的配置文件【.bashrc】 step2.使用vi命令编辑文件&#xff0c;在最后一行添加如下内容。 export PS1[\u\h $PWD]$ step3.使修改后的文件立即生效 source .bashrc

叮~程序员,你的专属1024程序员节已到账,请注意查收!

“1024&#xff0c;怎么过&#xff1f;” “&#xff1f;&#xff1f;&#xff1f;” “呆子。程序员节&#xff01;” 鲁迅曾说&#xff1a;世界上本没有节日&#xff0c;关注的人多了&#xff0c;便成了节。(hahaha....bushi) 如此小众的节日&#xff0c;外行的人听了好奇&a…

uboot通过图像化界面配置 dns命令

一. 简介 之前文章简单介绍了 uboot图像化配置操作。地址如下&#xff1a; uboot图像化配置操作说明-CSDN博客 本文就以如何使能 dns 命令为例&#xff0c;讲解一下如何通过图形化界面来配置 uboot。 二. uboot 通过图像化界面配置 dns命令 这里所使用的 uboot的源码包&…

M1本地部署Stable Diffusion

下载安装 参考博客: 在Mac上部署Stable Diffusion&#xff08;超详细&#xff0c;AI 绘画入门保姆级教程&#xff09; 安装需要的依赖库 brew install cmake protobuf rust python3.10 git wget 可能中途会存在下载报错或者下载卡主的问题,需要切国内源 brew进行替换源: …

小黑子—spring:第一章

spring入门1.0 一 小黑子对spring基础进行概述1.1 spring导论1.2 传统Javaweb开发困惑及解决方法1.3 三大的思想提出1.3.1 IOC入门案例1.3.2 DI入门案例 1.4 框架概念1.5 初识spring1.5.1 Spring Framework 1.6 BeanFactory快速入门1.7 ApplicationContext快速入门1.8 BeanFact…

SpringBoot项目中的测试类,无法注入类,注入类为空

开发中&#xff0c;需要用到测试类来测试接口 我最开始使用的注入方式是Autowired&#xff0c;但是在执行测试时&#xff0c;注入类报空指针异常&#xff0c;一直为null 后来上网查到几种解决方案&#xff0c;最终在通过下述内容解决了&#xff1a; 1.测试类中添加注解 SpringB…

【云上探索实验室-码上学堂】免费学习领好礼!

走过路过&#xff0c;不要错过&#xff01;上云AI三步走&#xff0c;学着课程奖品有&#xff01; 亚马逊云科技又放福利了&#xff0c;为了让同学们更快入手Amazon CodeWhisperer&#xff0c;官方推出《云上探索实验室-码上学堂》活动&#xff0c;作为一名Amazon CodeWhisperer…

一种晶圆表面形貌测量方法-无图晶圆几何量测系统

晶圆检测机&#xff0c;又称为半导体芯片自动化检测设备&#xff0c;是用于对半导体芯片的质量进行检验和测试的专用设备。它可以用于硅片、硅晶圆、LED芯片等半导体材料的表面检测&#xff0c;通过对晶圆的表面特征进行全面检测&#xff0c;可以有效降低产品的不良率&#xff…

Z41H-40C明杆闸阀型号解析

Z41H-40C型号字母含义 Z41H-40C型号是德特森阀门常用的明杆闸阀型号字母分别代表的意思是: Z——代表阀门类别《闸阀》 4——代表连接方式《法兰》 1——代表结构形式《明杆》 H——代表密封材质《不锈钢合金》 -《分隔键》 40——代表公称压力《4.0MPA》 C——代表阀体…

MongoDB副本集调整节点

点击上方蓝字关注我 MongoDB的副本集&#xff08;Replica Set&#xff09;是一个高可用性、可扩展性和冗余性的数据库解决方案。它能够确保数据库的高可用性&#xff0c;同时保障了数据的安全性。在本文中&#xff0c;我们将探讨如何在一个已经包含三个数据节点的副本集集群中&…