当前位置: 首页 > 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 操作系统中安…...

华为eNSP中型企业局域网网络规划设计(下)

→b站传送门&#xff0c;感谢大佬← →华为eNSP中型企业局域网网络规划设计&#xff08;上&#xff09;← →拓扑图传送门&#xff0c;可以自己配置着玩← 配置ospf AR3 [AR3]ospf 1 router-id 3.3.3.3 //出口默认路由 [AR3-ospf-1]default-route-advertise always #area…...

C语言(指针)1

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…...

perl:用 MIDI::Simple 生成midi文件,用 pygame 播放 mid文件

在 csdn.net 下载 strawberry-perl-5.32.1.1-64bit.zip 解压安装在 D:\Strawberry\ 运行 cpan install MIDI::Simple D:\Strawberry\c\bin\gmake.exe test -- OK Running make install for CONKLIN/MIDI-Perl-0.84.tar.gz Installing D:\Strawberry\perl\site\lib\MIDI.pm I…...

数据库-脏读

脏读&#xff08;Dirty Read&#xff09;是数据库并发控制中的一个概念&#xff0c;指的是一个事务读取了另一个尚未提交的事务的修改。由于另一个事务的修改可能最终会被撤销&#xff08;即发生回滚操作&#xff09;&#xff0c;因此&#xff0c;当前事务读取到的数据可能是“…...

react 用合计项

在React中&#xff0c;如果你想要计算一个数组中的所有项目&#xff0c;你可以使用reduce方法。这是一个JavaScript内置的数组方法&#xff0c;它允许你累计数组中的值。 以下是一个简单的React组件示例&#xff0c;它计算一个商品列表中所有商品的总价&#xff1a; import…...

IP 地址追踪工具促进有效的 IP 管理

网络 IP 地址空间的结构、扫描和管理方式因组织的规模和网络需求而异&#xff0c;网络越大&#xff0c;需要管理的 IP 就越多&#xff0c;IP 地址层次结构就越复杂。因此&#xff0c;如果没有 IP 地址管理&#xff08;IPAM&#xff09;解决方案&#xff0c;IP 资源过度使用和地…...

快手蓝V商家电话采集软件操作教程

抖音作为全球最受欢迎的短视频平台之一&#xff0c;拥有庞大的用户基础。其中不乏拥有蓝V认证的大V用户&#xff0c;他们的手机号码对于一些市场营销人员来说是非常有价值的。但是&#xff0c;抖音并没有公开这些大V用户的手机号码&#xff0c;怎样采集到他们的手机号码呢&…...

工业机器人应用实践之玻璃涂胶(篇二)

工业机器人 接上篇文章&#xff0c;浅谈一下实践应用&#xff0c;具体以玻璃涂胶为例&#xff1a; 了解工业机器人在玻璃涂胶领域的应用认识工具坐标系的标定方法掌握计时指令的应用掌握人机交互指令的应用掌握等待类指令用法&#xff08;WaitDI、WaitUnitl 等&#xff09;认…...

C++ 455. 分发饼干

文章目录 一、题目描述二、参考代码 一、题目描述 示例 1: 输入: g [1,2,3], s [1,1] 输出: 1 解释: 你有三个孩子和两块小饼干&#xff0c;3个孩子的胃口值分别是&#xff1a;1,2,3。 虽然你有两块小饼干&#xff0c;由于他们的尺寸都是1&#xff0c;你只能让胃口值是1的孩…...

未来娱乐新地标?气膜球幕影院的多维体验—轻空间

在中国&#xff0c;一座独特的娱乐场所正在崭露头角&#xff1a;气膜球幕影院。这个融合了气膜建筑与激光投影技术的创新场所&#xff0c;不仅令人惊叹&#xff0c;更带来了前所未有的科幻娱乐体验。让我们一起探索这个未来的娱乐空间&#xff0c;感受其中的多维魅力。 现场演出…...