JVM 类加载机制(七)

1.加载,验证,准备,解析,初始化

​ JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程。

image-20231206214433666

1.1. 加载

​ 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的入口。注意这里不一定非得要从一个 Class 文件获取,这里既可以从 ZIP 包中读取(比如从 jar 包和 war 包中读取),也可以在运行时计算生成(动态代理),也可以由其它文件生成(比如将 JSP 文件转换成对应的 Class 类)。

1.2. 验证

​ 这一阶段的主要目的是为了确保 Class 文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

1.3. 准备

​ 准备阶段是正式为类变量分配内存并设置类变量的初始值阶段,即在方法区中分配这些变量所使用的内存空间。注意这里所说的初始值概念,比如一个类变量定义为:

public static int v = 8080;

​ 实际上变量 v 在准备阶段过后的初始值为 0 而不是 8080,将 v 赋值为 8080 的 put static 指令是程序被编译后,存放于类构造器方法之中。

但是注意如果声明为:

public static final int v = 8080;

​ 在编译阶段会为 v 生成 ConstantValue 属性,在准备阶段虚拟机会根据 ConstantValue 属性将 v赋值为 8080。

1.4. 解析

​ 解析阶段是指虚拟机将常量池中的符号引用替换为直接引用的过程。符号引用就是 class 文件中的:

  1. CONSTANT_Class_info
  2. CONSTANT_Field_info
  3. CONSTANT_Method_info

等类型的常量。

1.5. 符号引用

„ 符号引用与虚拟机实现的布局无关,引用的目标并不一定要已经加载到内存中。各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须是一致的,因为符号引用的字面量形式明确定义在 Java 虚拟机规范的 Class 文件格式中。

1.6. 直接引用

​ „ 直接引用可以是指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在。

1.7. 初始化

​ 初始化阶段是类加载最后一个阶段,前面的类加载阶段之后,除了在加载阶段可以自定义类加载器以外,其它操作都由 JVM 主导。到了初始阶段,才开始真正执行类中定义的 Java 程序代码。

1.8. 类构造器

​ 初始化阶段是执行类构造器方法的过程。方法是由编译器自动收集类中的类变量的赋值操作和静态语句块中的语句合并而成的。虚拟机会保证子方法执行之前,父类的方法已经执行完毕,如果一个类中没有对静态变量赋值也没有静态语句块,那么编译器可以不为这个类生成()方法。

注意以下几种情况不会执行类初始化:

  1. 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。

  2. 定义对象数组,不会触发该类的初始化。

  3. 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触发定义常量所在的类。

  4. 通过类名获取 Class 对象,不会触发类的初始化。

  5. 通过 Class.forName 加载指定类时,如果指定参数 initialize 为 false 时,也不会触发类初始化,其实这个参数是告诉虚拟机,是否要对类进行初始化。

  6. 通过 ClassLoader 默认的 loadClass 方法,也不会触发初始化动作。

2. 类加载器

​ 虚拟机设计团队把加载动作放到 JVM 外部实现,以便让应用程序决定如何获取所需的类,JVM 提供了 3 种类加载器:

2.1. 启动类加载器(Bootstrap ClassLoader)

​ 负责加载 JAVA_HOME\lib 目录中的,或通过-Xbootclasspath 参数指定路径中的,且被虚拟机认可(按文件名识别,如 rt.jar)的类。

2.2. 扩展类加载器(Extension ClassLoader)

​ 负责加载 JAVA_HOME\lib\ext 目录中的,或通过 java.ext.dirs 系统变量指定路径中的类库。

2.3. 应用程序类加载器(Application ClassLoader):

​ 负责加载用户路径(classpath)上的类库。

​ JVM 通过双亲委派模型进行类的加载,当然我们也可以通过继承 java.lang.ClassLoader实现自定义的类加载器。

image-20231206215531314

3. 双亲委派

​ 当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载。

​ 采用双亲委派的一个好处是比如加载位于 rt.jar 包中的类 java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个 Object 对象。

image-20231206215743603

4. OSGI**(动态模型系统)**

​ OSGi(Open Service Gateway Initiative),是面向 Java 的动态模型系统,是 Java 动态化模块化系统的一系列规范。

4.1. 动态改变构造

​ OSGi 服务平台提供在多种网络设备上无需重启的动态改变构造的功能。为了最小化耦合度和促使这些耦合度可管理,OSGi 技术提供一种面向服务的架构,它能使这些组件动态地发现对方。

4.2. 模块化编程与热插拔

​ OSGi 旨在为实现 Java 程序的模块化编程提供基础条件,基于 OSGi 的程序很可能可以实现模块级的热插拔功能,当程序升级更新时,可以只停用、重新安装然后启动程序的其中一部分,这对企业级程序开发来说是非常具有诱惑力的特性。OSGi 描绘了一个很美好的模块化开发目标,而且定义了实现这个目标的所需要服务与架构,同时也有成熟的框架进行实现支持。但并非所有的应用都适合采用 OSGi 作为基础架构,它在提供强大功能同时,也引入了额外的复杂度,因为它不遵守了类加载的双亲委托模型。

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

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

相关文章

强化学习第1天:强化学习概述

☁️主页 Nowl 🔥专栏《机器学习实战》 《机器学习》 📑君子坐而论道,少年起而行之 ​​ 文章目录 介绍 强化学习要素 强化学习任务示例 环境搭建:gym 基本用法 环境信息查看 创建智能体 过程可视化 完整代码 结语…

代码随想录算法训练营第三十六天|01背包问题 二维 ,01背包问题 一维 ,416. 分割等和子集

背包理论基础 01 背包(二维) 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。 背包最大重量为4。 物品为&#x…

Python小案例:while练习题

目录 while练习题:1、存款多少年能翻倍2.小球坠落长度计算3、猴子吃桃4、计算:1-23-4...99-100的和 while练习题: 1、存款多少年能翻倍 1万本金,年利息:0.0325,求连本带息多少年能翻倍 解析:…

Codeforces Round 913 (Div. 3) A~E(F,G更新中)

A.Rook(循环) 题意: 给出一个 8 8 8 \times 8 88的棋盘和一个棋子(可以任选上下左右四方向移动任意步数),问一次移动可以到达哪些格子。 分析: 使用for循环对棋子所在的行列进行遍历并输出…

「智慧城市」这一概念科学吗?还是炒作?

智慧城市是一个综合性的概念,它利用信息技术和创新概念,将城市的各个系统和服务集成起来,以提升城市运行效率、优化城市管理和服务,改善市民的生活质量。 具体来说,智慧城市涵盖了许多领域,包括城市规划、建…

数据通信的基础知识

目录 一、物理层的主要功能 二、物理层的特性 三、数据通信的几个术语 四、信道的几个基本概念 1、信道 2、基带信号 (1)基带调制常用编码方式 1)不归零码(NRZ:Non-Return to Zero) 2)…

MATLAB——二维小波的多层重构

%% 学习目标:二维小波的多层重构 %% 案例1 clear all; close all; load woman.mat; Xind2gray(X,map); [C,S]wavedec2(X,3,db4); %二维小波的多层分解 S C(1:38*38)0; %将小波的近似系数设置为0 Ywaverec2(C,S,db4); %二维小波的多层…

MYSQL全语法速查(含示例)

文章目录 1.从简单的查询开始查找所有记录(SELECT *)查找记录中的所有登录名(SELECT)查找登录名为admin的密码(WHERE)查找电话号码非空的记录(IS NOT NULL)查找所在城市为北京或者用户名字是李四的记录(OR)查找所在城市为北京并且用户名字是张三的记录(AND)查找用户名字是李四或…

组件的生命周期

目录​ 1:生命周期和生命周期函数的概念 2:组件创建的过程 3:组件创建阶段beforeCreate,created,beforeMount,mounted生命周期函数。 3.1:beforeCreate方法示例: 3.2&#xff1…

【数据结构】动态规划(Dynamic Programming)

一.动态规划(DP)的定义: 求解决策过程(decision process)最优化的数学方法。 将多阶段决策过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解。 二.动态规划的基本思想: …

团队git操作流程

项目的开发要求:(1)项目组厉员代码提交不少于20次 (2)项目组厉员每天提交不少于20次 (3)企业项目开发代码的每天的提交一般提交3-5次 (4)代码仓库的管理 git的基础操作流…

对于多台232modbus仪表低成本通讯的modbus转profinet网关

随着越来越多的仪表设备采用Modbus通信协议,其中又以232 Modbus仪表的应用最为广泛。而为了实现多台232 Modbus仪表低成本通信,Modbus转Profinet网关应运而生。Modbus转Profinet网关不仅能够实现多台仪表之间的数据传输,还能够保证通信的稳定…

【数据结构】——二叉树简答题模板

目录 一、树和二叉树的概念(一)二叉树的定义和性质(二)树和二叉树的区别 二、完全二叉树和满二叉树三、二叉树的遍历(一)由序列确定二叉树(二)不同遍历序列的关系 四、二叉树的性质&…

计算机操作系统3

1.虚拟机 VM 两类虚拟机的对比: 2.进程 进程的特征: 进程状态的转换(五大状态) 3.进程控制原语的作用 4.线程 ​​​​​线程的属性 实现方式 5.调度算法的评价指标

OpenCV-python下载安装和基本操作

文章目录 一、实验目的二、实验内容三、实验过程OpenCV-python的安装与配置python下载和环境配置PIP镜像安装Numpy安装openCV-python检验opencv安装是否成功 openCV-python的基本操作图像输入和展示以及写出openCV界面编程单窗口显示多图片鼠标事件键盘事件滑动条事件 四、实验…

【源码解析】聊聊阻塞队列之BlockingArrayQueue

阻塞队列 阻塞队列:顾名思义 首先它是一个队列,而一个阻塞队列在数据结构中所起的作用大致如下入所示。 当阻塞队列是空时,从队列中获取元素的操作将会被阻塞。当阻塞队列时满的时,往队列里添加元素的操作将会被阻塞。 试图从空的…

全球6G发展大会开幕,为什么我们需要6G

2023全球6G发展大会 由中国IMT-2030(6G)推进组、中国通信学会、重庆两江新区管理委员会联合主办的2023全球6G发展大会今天在重庆两江新区明月湖成功开幕,开幕式上发布了《6G网络架构展望》《6G无线系统设计原则和典型特征》白皮书。 《6G网络…

有向图的拓扑序列(拓扑排序)

给定一个 n 个点 m 条边的有向图,点的编号是 1 到 n,图中可能存在重边和自环。 请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出 −1。 若一个由图中所有点构成的序列 A 满足:对于图中的每条边 (x,y)&a…

现货白银简单介绍

在贵金属投资领域,现货白银是当前国际上最为流行、交投最为活跃的白银投资方式,其交易市场遍布全球,包括伦敦、苏黎世、纽约、芝加哥及香港等主要市场,是一种以杠杆交易和做市商的形式进行的现货交易。 现货白银可以说是当下交易模…

对String类的深入理解

String类: String类相信大家对这个类并不陌生,这就是我们熟悉的字符串类型,但是我们一开始只知道它是用来定义字符串的,并不知道它的底层原理,这里我们就来简单的分析一下String的底层原理,首先我们来看一下…