【JVM】类加载过程|双亲委派模型

server/2024/12/22 9:31:31/

目录

四、类加载过程

1.类加载过程

2.双亲委派模型(经典面试题)

什么是双亲委派模型

双亲委派模型的优点

 破坏双亲委派模型


四、类加载过程

1.类加载过程

咱们写的java代码,是.java文件(硬盘),一个java进程要跑起来,就需要把.java先变成.class文件(硬盘),加载到内存中,得到“类对象”,其中就执行了指令,要执行的CPU指令,都是通过字节码(进入内存中)让JVM翻译出来的

从上⾯的图⽚我们可以看出整个JVM执⾏的流程中,和程序员关系最密切的就是类加载的过程了,所以接下来我们来看下类加载的执⾏流程。

对于⼀个类来说,它的⽣命周期是这样的:

类加载的几个环节(八股)

1.加载:在硬盘上,找到对应的.class文件,读取文件内容

2.验证:检查.class里的内容,是否符合要求

3.准备:给类对象,分配内存空间(元数据区)(类加载最终要得到的就是类对象),会把这个空间里的数据先全都填充为0(此时,如果这个类有静态成员,值就是0)

4.解析:针对字符串常量来初始化,把刚才.class文件中的常量的内容取出来,放到“元数据区”

5.初始化:针对类对象进行初始化(不是针对对象初始化,和构造方法无关),给静态成员进行初始化,执行静态代码块

此时类对象就搞定了

后续代码就可以使用这个类对象,创建实例,或者使用里面的静态成员了


2.双亲委派模型(经典面试题)

提到类加载机制,不得不提的⼀个概念就是“双亲委派模型”

站在Java虚拟机的⻆度来看,只存在两种不同的类加载器:⼀种是启动类加载器(Bootstrap  ClassLoader),这个类加载器使⽤C++语⾔实现,是虚拟机⾃⾝的⼀部分;另外⼀种就是其他所有的类加载器,这些类加载器都由Java语⾔实现,独⽴存在于虚拟机外部,并且全都继承⾃抽象类java.lang.ClassLoader。

站在Java开发⼈员的⻆度来看,类加载器就应当划分得更细致⼀些。⾃JDK 1.2以来,Java⼀直保持着三层类加载器、双亲委派的类加载架构器


什么是双亲委派模型

它出现在“加载”环节(第一步),根据代码中的写的“全限定类名”(包名+类名)找到对应的.class文件

这个模型描述了JVM加载.class文件过程中,找文件的过程

“类加载模型”在JVM中包含的一个特定的模块/类,这个类负责完成后续的类加载工作

JVM中内置了三个类加载器,负责加载不同的类

1)BootstrapClaaLoader (相当于爷爷)

负责加载标准库的类

2)ExtentionClassLoader(相当于父亲)

负责加载JVM扩展库的类

3)ApplicationClassLoader(相当于儿子)

负责加载第三方库的类自己写的代码的类

 此处的“父子关系”不是通过类的继承表示的(不是父类子类),而是通过类加载器中存在一个“parent”这样的字段,指向自己的父亲,类似于二叉树中的“三叉实现形式”)

“双亲委派模型”本身翻译是不准确的,更准确的翻译:“父亲委派模型”,“单亲委派模型”

工作过程举例:

给定一个类的全限定类名:java111.Test

此时加载过程如下:

(1)工作从ApplicationClassLoader开始进行

ApplicationClassLoader并不会立即搜索第三方库的相关目录,而是把任务交给自己的父亲来进行处理

(2)工作就到ExtentionClassLoader

ExtentionClassLoader也不会立即搜索负责的扩展库的目录,也是把任务交给自己的父亲来处理

(3)工作就来到BootstrapClaaLoader

BootstrapClaaLoader也像交给自己的父亲来处理,但是它的parent指向null,只能自己处理,BootstrapClaaLoader尝试在标准库的路径中搜索上述的类

(4)工作回到了ExtentionClassLoader

此时就要搜索扩展库对应的目录了

如果找到了,就由当前的类加载器负责打开文件,读取文件等后续操作...

如果找不到,任务就还是要继续还给儿子来处理

(5)工作回到了ApplicationClassLoader

此时要搜索第三方库/用户项目代码的目录了

如果找到了,也就是由当前的类加载器负责处理

如果没有找到,任务还是要继续还给儿子来处理

but,此时没有儿子了,还没找到,最早就会抛出一个ClassNotFoundException

本质就是:拿到任务,先交给父亲处理,父亲处理不了,在自己处理


双亲委派模型的优点

1. 避免重复加载类:⽐如A类和B类都有⼀个⽗类C类,那么当A启动时就会将C类加载起来,那么在B类进⾏加载时就不需要在重复加载C类了。

2. 安全性:使⽤双亲委派模型也可以保证了Java的核⼼API不被篡改,如果没有使⽤双亲委派模型,⽽是每个类加载器加载⾃⼰的话就会出现⼀些问题,⽐如我们编写⼀个称为java.lang.Object类的话,那么程序运⾏的时候,系统就会出现多个不同的Object类,⽽有些Object类⼜是⽤⼾⾃⼰提供的因此安全性就不能得到保证了(JVM会确保加载的类是标准库的类)


 破坏双亲委派模型

but 双亲委派模型虽然有其优点,但在某些情况下也存在⼀定的问题,⽐如Java中SPI(Service Provider Interface,服务提供接⼝)机制中的JDBC实现:

因为DriverManager位于rt.jar包,由BootStrap类加载器加载,⽽其Driver接⼝的实现类是位于服务商提供的Jar包中,是由⼦类加载器(线程上下⽂加载器 Thread.currentThread().getContextClassLoader)来加载的,这样就破坏了双亲委派模型了(双亲委派模型讲的是所有类都应该交给⽗类来加载,但JDBC显然并不能这样实现)


http://www.ppmy.cn/server/115785.html

相关文章

iOS——weak修饰符的学习补充

Weak修饰符的内部机制 SideTable ObjectC中对对象的存储,实现上做了一定的优化,一旦有弱引用对象被赋值,即运行时(Runtime)会在全局的SideTables中分配一个SideTable空间,此空间是根据对象的地址相关算法…

7.统一网关-Gateway

文章目录 1.统一网关介绍2.网关开发3.predicate4.Route Predicate Factories(路由断言工厂)4.1Path 路由断言工厂4.2.Method 路由断言工厂4.3 Header 路由断言工厂4.4 Query 路由断言工厂4.5 Host 路由断言工厂4.6 After 路由断言工厂4.7 Before 路由断言工厂4.8 Between 路由断…

自己看---华为od--敏感字段加密

题目描述 给定一个由多个命令字组成的命令字符串: 字符串长度小于等于127字节,只包含大小写字母,数字,下划线和偶数个双引号; 命令字之间以一个或多个下划线_进行分割; 可以通过两个双引号””来标识包含下…

拓数派荣登2024年《财富》中国最具社会影响力的创业公司

9月11日,全球著名商业杂志《财富》(Fortune Magazine)在其中文版发布“2024年中国最具社会影响力的创业公司”榜单。拓数派凭借基础AI理论、产品在核心领域应用,AI向善品牌影响力等方面的综合竞争力荣誉上榜。 作为《财富》最具权威性的榜单…

设计模式-行为型模式-迭代器模式

1.迭代器模式的定义 迭代器模式提供一种对容器对象中的各个元素进行访问的方法,而不需要暴露该对象的内部细节; 在软件系统中,容器对象有两个职责:一是存储数据,二是遍历数据;从依赖性上看,前者…

测试开发基础——软件测试中的bug

二、软件测试中的Bug 1. 软件测试的生命周期 软件测试贯穿于软件的整个生命周期 需求分析 测试计划 测试设计与开发 测试执行 测试评估 上线 运行维护 用户角度:软件需求是否合理 技术角度:技术上是否可行,是否还有优化空间 测试角度…

ARM32开发——DMA

🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 基础概念CPURAM外设 ARM32程序存储 执行过程取数据 执行操作流程总结 基础概念 CPU CPU(Central Processing Unit&am…

浅谈AI伦理与社会的影响

引言 1.1 AI技术的发展与社会影响 人工智能(AI)技术自20世纪50年代诞生以来,经历了多次技术革新和应用扩展,如今已成为推动社会进步的重要力量。AI技术的快速发展不仅在科技领域取得了显著成就,也在社会各个层面产生…