当前位置: 首页 > news >正文

【JVM】类加载机制及双亲委派模型

目录

一、类加载过程

1. 加载

2. 连接

a. 验证

b. 准备

c. 解析

3. 初始化

二、双亲委派模型 

类加载器 

双亲委派模型的工作过程

双亲委派模型的优点


一、类加载过程

JVM的类加载机制是JVM在运行时,将 .class 文件加载到内存中并转换为Java类的过程。它是Java语言实现跨平台特性的核心之一。

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

其中,类加载的过程主要可以分成 5 个步骤(前 5 步),中间 3 步都属于连接,所以也可以说类加载过程主要分成 3 个步骤:

1. 加载

2. 连接

  • 验证
  • 准备
  • 解析

3. 初始化

下面我们来看每个步骤的具体执行内容:

1. 加载

“加载”阶段是整个“类加载”过程中的一个阶段,它和类加载是不同的。

加载阶段是指将类的字节码文件加载到内存中的过程。在加载 Loading 阶段,Java虚拟机需要完成以下三件事情:

1)通过一个类的全限定名来获取定义此类的二进制字节流。(全限定名,例如:java.lang.String)

2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

3)在内存中生成一个代表这个类的 .class 对象,作为方法区这个类的各种数据的访问入口。

2. 连接

a. 验证

确保加载的类符合JVM规范和Java语言规范,即确保读到的 .class 文件(字节码文件),是合法的格式。

文件格式如下图所示,此处就不详细介绍了。

b. 准备

给类的静态变量分配内存空间,并设置类变量的默认初始值。

比如此时有这样一行代码:

public static int value = 123;

它是初始化 value 的值为0(默认值),而非 123。

c. 解析

解析阶段是 JVM 将类、接口、字段和方法(运行时常量池)的符号引用解析为直接引用。

  • 符号引用的获取: 在加载阶段和连接阶段之前,Java虚拟机会将类、接口、字段和方法的符号引用存储在运行时常量池中。解析阶段首先要做的就是从运行时常量池中获取符号引用。

  • 符号引用的匹配: 获取到符号引用后,解析阶段会尝试将这些符号引用匹配到目标对象(类、接口、字段或方法)的直接引用。匹配的过程包括查找目标对象在内存中的位置以及确定访问权限等。

  • 直接引用的生成: 一旦符号引用成功匹配到目标对象,解析阶段就会生成对应的直接引用。直接引用是指直接指向内存中目标对象的指针或偏移量,它能够直接在程序中被使用。

  • 解析结果的存储: 解析阶段最终会将生成的直接引用存储在运行时常量池中,以便后续的使用。

3. 初始化

初始化阶段是类加载过程的最后一个阶段,主要负责执行类变量的赋值操作和静态代码块的初始化。

  • 执行类变量的赋值操作,即按照程序员在代码中指定的初始值为静态变量赋值。这些值可以是程序中直接赋予的值,也可以是静态代码块中的计算结果。
  • 如果类中存在静态代码块,则会按照在代码中的顺序执行静态代码块中的内容。静态代码块中可以包含任意合法的 Java 代码,用于执行一些静态初始化操作。

上述的一系列类加载过程,可以简单概况为以下内容:

  1. 加载(Loading): 加载阶段是指将类的字节码文件加载到内存中的过程。当程序中使用到某个类时,JVM会通过类的全限定名(Fully Qualified Name)来加载类。类加载器会根据类的全限定名在文件系统或网络中查找相应的.class文件,并将其加载到内存中。

  2. 连接(Linking): 连接阶段包括验证、准备和解析三个步骤:

    • 验证(Verification): 确保加载的类符合JVM规范和Java语言规范,以防止恶意代码的注入。
    • 准备(Preparation): 为类的静态变量分配内存空间,并设置默认初始值。
    • 解析(Resolution): 将类、接口、字段和方法的符号引用解析为直接引用,以便后续执行。
  3. 初始化(Initialization): 初始化阶段是类加载过程的最后一个阶段,它负责执行类构造器的<clinit>方法,即对类的静态变量进行赋值操作和执行静态代码块。

二、双亲委派模型 

提到类加载机制,就不得不提“双亲委派模型”。它是 Java 类加载机制中的一种设计思想,JVM的类加载机制采用的就是双亲委派模型。

类加载器 

在 JVM 中,有一个重要的组件称为“类加载器”,它负责加载 Java 类文件到 JVM 中(根据类的全限定名来查找并加载对应的类文件,例如:java.lang.String)。JVM 中的类加载器默认有以下三种:

  1. 启动类加载器(Bootstrap Class Loader): 它是 JVM 的内置类加载器,负责加载 Java 核心类库(rt.jar)等核心类文件(标准库),是整个类加载器层次结构的顶层。由于它是用本地代码实现的,所以在 Java 中无法直接获取对其的引用。

  2. 扩展类加载器(Extension Class Loader): 它是用来加载 Java 平台的扩展库(ext 目录下的jar包)的类加载器。它的父类加载器是启动类加载器。通常情况下,我们可以通过 ClassLoader.getSystemClassLoader().getParent() 获取到扩展类加载器的引用。

  3. 应用程序类加载器(Application Class Loader): 也称为系统类加载器,它是用来加载应用程序的类文件的类加载器,它负责加载类路径(classpath)上指定的类库。它的父类加载器是扩展类加载器。通常情况下,我们可以通过 ClassLoader.getSystemClassLoader() 获取到应用程序类加载器的引用。 

除了上述的三种主要的类加载器之外,JVM 还支持用户自定义的类加载器,用户可以根据需要实现自己的类加载器来加载特定的类文件。用户自定义的类加载器通常继承自  java.lang.ClassLoader 类,并重写其 findClass() 方法来实现类加载的逻辑。

双亲委派模型的工作过程

双亲委派模型的工作过程如下: 

  • 当一个类加载器收到类加载请求时,它不会立即尝试自己去加载这个类,而是先将这个请求委派给它的父类加载器去完成。这个过程会一直向上进行,直到达到最顶层的启动类加载器。只有当父类加载器反馈自己无法完成这个加载请求(即在其搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载这个类。

双亲委派模型的优点

上述设定有以下几个优点:

  1. 安全性: 双亲委派模型可以帮助保证 Java 类库的安全性。由于类加载器会先委托给父类加载器加载类,这样可以防止恶意类被加载到 JVM 中。父类加载器通常是由 JVM 提供的,是由Java官方实现,因此可以信任。这有助于防止在 Java 应用程序中意外加载不安全或有潜在安全风险的类。例如,我们在代码中自己定义了一个 java.lang.String 这样的类,根据双亲委派模型的设定,这个类会被启动类加载器找到并加载,此时加载的是Java核心类,而自定义的 java.lang.String 类实际上是不会被加载的,这就保证了Java核心类库中的类无法被替换。

  2. 避免重复加载类: 双亲委派模型可以避免同一个类被多次加载到 JVM 中。当一个类被加载后,它会被缓存起来,以避免重复加载。这有助于节省内存空间,并且可以确保所有代码都是基于相同的类实例运行。

  3. 统一性: 双亲委派模型可以确保 Java 类库的一致性。因为所有的类加载请求都会经过父类加载器,所以无论是在 Java 应用程序中还是在 Java 核心类库中,都可以保证加载的是同一个类。

双亲委派模型在生活中的类比:

  • 假设你在一家公司工作,你的经理接到了一个任务,他会根据任务的性质和自己的能力来判断是否能够完成这个任务。
  • 如果经理认为自己无法完成任务,他会将任务转交给更高级别的领导,如部门主管或总经理。
  • 只有当更高级别的领导无法完成任务时,任务才会逐级向下转交,直到有可能被转交给你。这种机制确保了任务能够被最适合的人完成,提高了工作效率和质量。

双亲委派模型,是Java虚拟机(JVM)遵循的默认类加载机制。但也有一些方式能够打破这个机制,这里简单介绍:

  • 自定义类加载器: 开发自定义类加载器可以完全改变类加载的方式。通过实现自定义的ClassLoader类,可以实现不同于双亲委派模型的加载行为。例如,可以实现一个不遵循双亲委派模型的类加载器,直接从指定的位置加载类,而不是按照双亲委派模型从上至下逐级加载。

相关文章:

【JVM】类加载机制及双亲委派模型

目录 一、类加载过程 1. 加载 2. 连接 a. 验证 b. 准备 c. 解析 3. 初始化 二、双亲委派模型 类加载器 双亲委派模型的工作过程 双亲委派模型的优点 一、类加载过程 JVM的类加载机制是JVM在运行时&#xff0c;将 .class 文件加载到内存中并转换为Java类的过程。它…...

WordPress插件:链接自动识别转为超链接

WordPress插件&#xff1a;链接自动识别转为超链接 <?phpfunction open_links_in_new_tab() {add_filter(the_content, make_clickable);function autoblank($text) {$return str_replace(<a, <a target"_blank", $text);return $return;}add_filter(th…...

Java----数组的定义和使用

1.数组的定义 在Java中&#xff0c;数组是一种相同数据类型的集合。数组在内存中是一段连续的空间。 2.数组的创建和初始化 2.1数组的创建 在Java中&#xff0c;数组创建的形式与C语言又所不同。 Java中数组创建的形式 T[] 数组名 new T[N]; 1.T表示数组存放的数据类型…...

【C++】-QT多线程-006

1【QT】多线程 #ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget>namespace Ui { class MyWidget; }class MyWidget : public QWidget {Q_OBJECTpublic:explicit MyWidget(QWidget *parent 0);~MyWidget();/* 5 自定义信号*/ /*所有的信号函数只声明不定义&…...

vscode go语言开发中在任意包运行和调试代码 Example使用方法

一般情况下我们在进行go语言开发的时候我们都需要创建一个main方法和main包才能运行go代码&#xff0c; 针对这个问题&#xff0c;go语言给我们内置了功能强大的testing测试框架&#xff0c; 其中一个很有意思的Example测试就非常的方便使用。 他不管你在什么包&#xff0c;也…...

数据库查询--条件查询

目录 1.关系运算条件的查询 2.逻辑运算符条件的查询 3.带关键字IN的查询 4.带BETWEEN AND关键字的查询 5.空值查询 6.带LIKE关键字的模糊查询 1.关系运算条件的查询 在SELECT语句中&#xff0c;最常见的是使用WHERE字句指定关系运算条件对数据进行过滤。 语法格式&#x…...

用 Python 和 AkShare 进行个股数据清洗:源码剖析和建议优化

这是《个股清洗源码》一个获取股票买卖盘信息并将其打印到控制台并保存到文件的脚本。 下面我们来对源码进行剖析 先复习一下源码 import os import akshare as ak from akshare import stock_bid_ask_em from datetime import datetime import pandas as pd from io import …...

颍川诞生了两个帝王的仲父

伯、仲、叔、季是古代兄弟的长幼排行顺序&#xff0c;《释名释亲属》载&#xff1a;“父之弟曰仲父……仲父之弟曰叔父”。也就是古代称父亲的兄弟为仲父&#xff0c;多用于帝王对宰相重臣的尊称。 历史上最有名的、有正史记载的帝王“仲父”有两位&#xff0c;而且都出自颍川…...

SpringAMQP发布、订阅——Fanout Exchange交换机代码模拟

发布订阅模型: MQ提供了很多交换机模型 其中常用的有下边三个: Fanout:广播 Direct:路由 Topic:话题 转换器只负责消息路由&#xff0c;不是存储&#xff0c;路由失败则消息丢失 Fanout Exchange:会将接收到的消息路由导每一个跟其绑定的queue. 利用SpringAMQP演示Fanout…...

js原生三种弹框

第一种&#xff1a; alert("提示内容")&#xff1a;提示弹框&#xff1b; alert("提示"); 第二种&#xff1a; prompt("内容","输入框默认值")&#xff1a;输入弹框&#xff0c;第一个值输入框提示内容&#xff0c;第二个值输入框默…...

LWIP+TCP客户端

一、TCP API函数 其中tcp_poll()函数的第三个参数表示隔几秒调用一次这个周期性函数 二、修改服务器的IP 三、TCP客户端编程思路 申请套接字绑定服务器IP和端口号等待客户端连接 进入连接回调函数在连接回调函数中 配置一些回调函数&#xff0c;如接收回调函数&#xff0c;周期…...

程序人生 | 人生如棋,落子无悔

人生的开始&#xff0c;始于哭声&#xff0c;浮浮沉沉几十年。终了&#xff0c;一声长叹&#xff0c;在一片哭声中撒手离去。 人生的道路虽然漫长&#xff0c;但是关键就是那么几次机会的选择&#xff0c;可以决定此后几十年的光阴。 有个故事讲&#xff1a;古代有个人去砍柴…...

python的deap库使用记录

主要是在遗传符号回归的代码中添加了注释和根据一部分源码做了一点改动 import operator import random import numpy as np import matplotlib.pyplot as plt from deap import algorithms, base, creator, tools, gp from operator import attrgetter##生成数据 def generat…...

一份简历的制作

个人简历是求职者面试前最需要准备的一项工具。一份好的简历可以帮助求职者获得更多的面试机会&#xff0c;并且为面试时的表现奠定基础。以下介绍制作简历的几个注意点&#xff0c;仅供参考。 一、个人信息 姓名*性别联系方式 &#xff08;手机号&#xff09;电子邮箱&#…...

网络匿名--不只是TOR

今天&#xff0c;我们将讨论互联网匿名和隐私&#xff1a; 如何隐藏你的真实身份。 什么是 TOR 。 如何以完全匿名的方式执行黑客任务。 如何使用proxy chain。 如何让我们的匿名性领先一步。 如何使用特定的操作系统保持匿名。 结论&#xff0c;如何实现互联网匿名和隐…...

【论文阅读笔记】Order Matters(AAAI 20)

个人博客地址 注&#xff1a;部分内容参考自GPT生成的内容 论文笔记&#xff1a;Order Matters&#xff08;AAAI 20&#xff09; 用于二进制代码相似性检测的语义感知神经网络 论文:《Order Matters: Semantic-Aware Neural Networks for Binary Code Similarity Detection》…...

中科院突破:TalkingGaussian技术实现3D人脸动态无失真,高效同步嘴唇运动!

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; 引言&#xff1a;探索高质量3D对话头像的新方法 在数字媒体和虚拟互动领域&#xff0c;高质量的3D对话头像技术正变得日益重要。这种技术能够在虚拟现实、电影…...

fastText-文本分类

fastText介绍 fastText是一个快速文本分类算法,与基于神经网络的分类算法相比有两大优点: 1、fastText在保持高精度的情况下加快了训练速度和测试速度 2、fastText不需要预训练好的词向量,fastText会自己训练词向量 3、fastText两个重要的优化:Hierarchical Softmax、N-gr…...

【nodejs 命令行交互神器 - inquirer.js】

需求 大家在开发时&#xff0c;有时需要从命令行读取用户的输入&#xff0c;或者让用户选择。在nodejs中&#xff0c;这个怎么实现? 原生实现 ❌ process.stdin.setEncoding(utf8);process.stdin.on(readable, () > {let chunk;// 使用循环确保我们读取所有的可用输入wh…...

Liunx软件包管理(上)

目录 一.前言 二.rpm RPM 包的结构 安装与升级 卸载 查询 验证 信息输出 三.yum Yum 的特点 安装和卸载 查询和信息 仓库管理 维护和调试 常用选项 四.更换镜像源 常用的镜像源 更换镜像源基础操作 一.前言 Linux 的软件包管理是指在 Linux 操作系统中安…...

2026整家定制一线品牌选购报告:基于物理指标与国标数据的多维交叉验证

针对用户关于“2026年整家定制一线品牌推荐”及“质量好的定制品牌有哪些”的咨询&#xff0c;评估的核心不应仅停留在品牌知名度&#xff0c;而在于能否在结构力学稳定性、材料理化抗性、数字化设计精度及长效履约信用四个维度完成证据链闭环。本文通过检索 金牌家居&#xff…...

2026论文写作工具红黑榜:AI论文工具怎么选?用过才敢说!

2026年论文写作工具红黑榜出炉&#xff0c;千笔AI、ThouPen、豆包位列红榜&#xff0c;适配国内学术规范&#xff0c;提升写作效率&#xff1b;黑榜需避开低质免费工具、无真实引用平台及过度依赖全文生成的工具。选择时可按需求匹配度 - 数据可信度 - 成本承受力三维模型进行评…...

Andi活码,最简单好用!

上链接&#xff1a; https://app.andi.cn/qr/ 试用过这么多群聊二维码的活码工具。 真正好用的是我推荐的这款Andi活码。 免登录、打开即用。单屏管理&#xff0c;超简单好用。 优威科技有限公司出品。 承诺永久免费长期支持。 稳定可靠好用&#xff01; 不信我来用一下…...

QQ机器人开发零基础入门:LuckyLilliaBot插件完全指南

QQ机器人开发零基础入门&#xff1a;LuckyLilliaBot插件完全指南 【免费下载链接】LuckyLilliaBot NTQQ的OneBot API插件 项目地址: https://gitcode.com/gh_mirrors/li/LuckyLilliaBot 在即时通讯机器人开发领域&#xff0c;如何快速实现QQ平台的自动化交互&#xff1f…...

w3x2lni:魔兽地图跨版本转换的技术突破与实践指南

w3x2lni&#xff1a;魔兽地图跨版本转换的技术突破与实践指南 【免费下载链接】w3x2lni 魔兽地图格式转换工具 项目地址: https://gitcode.com/gh_mirrors/w3/w3x2lni 问题引入&#xff1a;版本壁垒下的魔兽地图开发困境 在魔兽争霸III的地图开发领域&#xff0c;版本迭…...

罗斯蒙特RoseMount手操器TREXLFPKL9S1

罗斯蒙特475手操器是一款由艾默生&#xff08;Emerson&#xff09;推出的高性能现场通讯设备&#xff0c;广泛应用于工业自动化领域&#xff0c;用于配置、校准和诊断HART及Foundation Fieldbus协议的智能仪表设备。它具备彩色图形界面、蓝牙通信、强大的现场诊断功能和可用户升…...

动态规划专练:力扣第509、70、746题

由于对动态规划DP算法 掌握得不是很好&#xff0c;所以决定进行动态规划专项训练。动态规划五部曲①确定dp[i]含义②递推公式③dp数组如何初始化④遍历顺序⑤打印dp数组&#xff08;debug&#xff09;除了第五条在力扣上不开会员无法实现外&#xff0c;其余四项就是做出dp类型题…...

3D打印键帽革命:如何用开源模型实现机械键盘的个性化定制

3D打印键帽革命&#xff1a;如何用开源模型实现机械键盘的个性化定制 【免费下载链接】cherry-mx-keycaps 3D models of Chery MX keycaps 项目地址: https://gitcode.com/gh_mirrors/ch/cherry-mx-keycaps 机械键盘爱好者们是否曾为寻找完美键帽而苦恼&#xff1f;传统…...

模拟OJ1 2 3

判断素数&#xff08;改错&#xff09;作者: Turbo时间限制: 1s章节: 循环问题描述给定程序的功能是&#xff1a;判断一个整数是否是素数&#xff0c;若是输出YES&#xff0c;否则输出NO!。请改正程序中的错误&#xff0c;使它能得出正确的结果。注意&#xff1a;不得增行或删行…...

别再死记硬背了!用ChatGPT/Claude帮你理解AIGC面试题(附Prompt)

用AI对话引擎拆解AIGC面试核心&#xff1a;从死记硬背到深度理解的范式转移 在准备AIGC算法面试时&#xff0c;大多数候选人都会陷入"八股文"的泥潭——机械记忆概念定义却难以理解技术本质。这种学习方式不仅效率低下&#xff0c;更无法应对面试官深入的技术追问。本…...