类加载的过程是怎样的?

article/2025/9/26 15:56:09

写在前面

本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

本专栏目录结构和文献引用请见100个问题搞定Java虚拟机

解答

JVM加载java类就是将字节流(如.class文件,网络传输的字节流)文件加入到内存中的过程,分为以下三步:加载、链接、初始化
1. 加载是指查找字节流,并且据此创建类的过程。加载需要借助类加载器,在 Java 虚拟机中,类加载器使用了双亲委派模型,即接收到加载请求时,会先将请求转发给父类加载器。
2. 链接,是指将创建成的类合并至 Java 虚拟机中,使之能够执行的过程。链接还分验证、准备和解析三个阶段。其中,解析阶段为非必须的。
3. 初始化,则是为标记为常量值的字段赋值,以及执行 <clinit> 方法的过程。
类的初始化仅会被执行一次,这个特性被用来实现单例的延迟初始化。

补充

加载

Java 将字节码数据从不同的数据源读取到 JVM 中,并映射为 JVM 认可的数据结构(Class 对象)。

这里的数据源可能是各种各样的形态,如 jar 文件、class 文件,甚至是网络数据源等;

如果输入数据不是 ClassFile 的结构,则会抛出 ClassFormatError。

加载规则

双亲委派机制

详情请见我的另一篇博客——双亲委派模型是什么?

类的唯一性

类加载器名称+类全限定名称

链接

这是核心的步骤,简单说是把原始的类定义信息平滑地转化入 JVM 运行的过程中。

验证

这是虚拟机安全的重要保障,JVM 需要核验字节信息是符合 Java 虚拟机规范的,否则就被认为是 VerifyError,这样就防止了恶意信息或者不合规的信息危害 JVM 的运行,验证阶段有可能触发更多 class 的加载。

准备

创建类或接口中的静态变量,并初始化静态变量的初始值。

但这里的“初始化”和下面的显式初始化阶段是有区别的,侧重点在于分配所需要的内存空间,不会去执行更进一步的 JVM 指令。

解析

将符号引用解析为实际引用, 符号引用是在编译阶段由编译器生成,包含目标方法所在类的名字、目标方法的名字、接收参数类型以及返回值类型

初始化

这一步真正去执行类初始化的代码逻辑,包括

  1. 静态字段赋值的动作
  2. 执行类定义中的静态初始化块内的逻辑

编译器在编译阶段就会把这部分逻辑整理好,父类型的初始化逻辑优先于当前类型的逻辑。

具体来说就是为标记为常量值的字段(基本类型或字符串且被修饰为final)赋值,以及执行方法(其他赋值操作和静态代码块)。

类的初始化过程是线程安全的,并且只能被初始化一次。jvm会通过加锁来保证方法仅被执行一次。

初始化的时机

对一个类的主动引用

被动引用并不会引发类的初始化,如引用类的静态常量,引用父类的静态字段不会初始化子类,数组定义来引用类不会导致初始化。

JDK9

在 JDK 9 中,由于 Jigsaw 项目引入了 Java 平台模块化系统(JPMS),Java SE 的源代码被划分为一系列模块。

平台类加载器(Platform Class-Loader)

  1. 扩展类加载器被重命名为平台类加载器(Platform Class-Loader),而且 extension 机制则被移除。
    也就意味着,如果我们指定 java.ext.dirs 环境变量,或者 lib/ext 目录存在,JVM 将直接返回错误!
    建议解决办法就是将其放入 classpath 里。

  2. 部分不需要 AllPermission 的 Java 基础模块,被降级到平台类加载器中,相应的权限也被更精细粒度地限制起来。

  3. rt.jar 和 tools.jar 同样是被移除了! JDK 的核心类库以及相关资源,被存储在 jimage 文件中,并通过新的 JRT 文件系统访问,而不是原有的 JAR 文件系统。
    虽然看起来很惊人,但幸好对于大部分软件的兼容性影响,其实是有限的,更直接地影响是 IDE 等软件,通常只要升级到新版本就可以了。

  4. 增加了 Layer 的抽象, JVM 启动默认创建 BootLayer,开发者也可以自己去定义和实例化 Layer,可以更加方便的实现类似容器一般的逻辑抽象。

结合了 Layer,目前的 JVM 内部结构就变成了下面的层次,内建类加载器都在 BootLayer 中,其他 Layer 内部有自定义的类加载器,不同版本模块可以同时工作在不同的 Layer。

Java平台模块化系统


http://chatgpt.dhexx.cn/article/VY0E5O2N.shtml

相关文章

类加载(基本说明、流程图、类加载各个阶段完成的任务)

目录 基本说明 类加载过程流程图 类加载各阶段完成的任务 加载阶段 ​编辑 连接阶段-验证 连接阶段-准备 连接阶段-解析 Initialization&#xff08;初始化) 类加载就是当字节码文件有了过后&#xff0c;进行下一步工作&#xff0c;不管是创建对象&#xff0c;还是干其…

什么是类的加载

一、什么是类的加载 java文件通过编译器变成了.class文件&#xff0c;接下来类加载器又将这些.class文件加载到JVM中。其中类装载器的作用其实就是类的加载。 其实&#xff0c;类加载器并不需要等到某个类被“首次主动使用”时再加载它&#xff0c;JVM规范允许类加载器在预料…

Windows下cmd命令—systeminfo

该命令是Windows中用于显示关于计算机及其操作系统的详细配置信息&#xff0c;包括操作系统配置、安全信息、产品 ID 和硬件属性&#xff0c;如 RAM、磁盘空间和网卡和补丁信息等。 例如&#xff1a;查看自己的计算机是32位还是64位 可以通过如下步骤&#xff1a; ①首先&…

SysInfoTools MS SQL Transaction Log Recovery 22.0

SysInfo DBF 修复工具专门用于修复由 dBase II IV、V Visual FoxPro、Clipper、dBXL、dBFast、CodeBase、MultiBase、Arago 生成的损坏、损坏和无法访问的 DBF 文件。从 SysInfoTools 下载最新和更复杂的基于 Windows 的应用程序 DBF 恢复实用程序&#xff0c;它可以一次性完美…

MASM32编程完善SysInfo遇到奇怪故障,真切感受全局变量和局部变量之别……

SysInfo主要是通过WMI来获取系统信息的&#xff0c;但是WMI获取的操作系统信息中没有Windows操作系统是32位还是64位的内容&#xff0c;所以需要另外想办法编程获取&#xff0c;比较常见的方法是调用Windows API函数GetNativeSystemInfo()或IsWow64Process()。之前分别用MASM32…

系统信息:uname,sysinfo,gethostname,sysconf

且欲近寻彭泽宰&#xff0c;陶然共醉菊花怀。 文章目录 系统信息系统标识 unamesysinfo 函数gethostname 函数sysconf()函数 系统信息 系统标识 uname 系统调用 uname()用于获取有关当前操作系统内核的名称和信息&#xff0c;函数原型如下所示&#xff08;可通过"man 2 …

Django-搭建sysinfo获取系统信息

文章目录 前言一、项目搭建二、主机信息监控三、Celery定时任务和异步任务 前言 使用Django&#xff0c;搭建sysinfo&#xff0c;Linux中,sysinfo是用来获取系统相关信息的结构体 本篇基于&#xff1a;https://github.com/hypersport/sysinfo#readme项目借鉴路径: https://gi…

SysInfo(电脑系统信息)0.0.0.1beta2

文件说明符 : D:\masm32\wmi\sysInfo\sysInfo0.0.0.1beta2.exe 属性 : A--- 数字签名:否 PE文件:是 语言 : 中文(简体&#xff0c;中国) 文件版本 : 0.0.0001 beta2 说明 : 电脑系统信息 版权 : PurpleEndurer 产品版本 : 0.0.0001 beta2 产品名称 : 电脑系统信息 公司名称 : P…

sysinfo函数、结构体使用

1&#xff0c;头文件&#xff1a; #include <sys/sysinfo.h>2&#xff0c;函数声明&#xff1a; int sysinfo(struct sysinfo *info);3&#xff0c;返回值&#xff1a; 成功返回0&#xff0c;错误返回-1&#xff1b; 4&#xff0c;sysinfo结构体名称 Linux 2.3.23(i38…

Linux中sysinfo的用法

sysinfo结构体 Linux中,可以用sysinfo来获取系统相关信息。 Linux中,sysinfo是用来获取系统相关信息的结构体。 函数声明和原型&#xff1a; #include <sys/sysinfo.h> int sysinfo(struct sysinfo *info); 在Linux中不同对版本结构体不一样 在Linux 2.3.16中&#…

sysinfo 函数

在linux系统中&#xff0c;我们可以使用sysinfo()获取一些系统统计信息。我们在终端命令行中输入“man 2 sysinfo”即可获取sysinfo()的详细信息&#xff0c;如下图所示。 从上图可以知道&#xff0c;使用uname需要包含头文件"#include <sys/sysinfo.h>" sysi…

natapp

简介 natapp是一个内网穿透工具&#xff0c;内网穿透也叫做内网映射&#xff0c;也叫“NAT穿透”&#xff0c;所谓内网穿透简单来说就是让外网能够访问内网&#xff0c;即把自己的电脑当服务器&#xff0c;让别人能够访问自己的电脑。 使用 1、注册一个账号&#xff0c;并且进…

WAP PUSH

PUSH &#xff08;WAP-PUSH&#xff09;又叫做服务信息或推入信息&#xff0c;是一种特殊格式的短信。 目录 基本简介 特点优势 系统框架 推送协议 推送服务方式 短消息网关简介 基于短信网关发送WAP PUSH wapPDU 模式 分析 良好前景 基本简介 特点优势 系统框架 推送协议 推送…

睡眠 应该用 a加权 c加权_时间加权平均价格算法(TWAP)和成交量平均算法(VWAP)在量化回测的应用...

本应用实践平台为BigQuant人工智能量化平台 为什么要引入TWAP和 VWAP&#xff1f; 为了评估策略的资金容量&#xff0c;我们对M.trade模块里买入点和卖出点这两个参数进行了更丰富的扩展&#xff0c;支持了策略能够按更丰富的算法交易价格&#xff08;WAP&#xff09;进行撮合。…

【Java使用pushy(com.eatthepath)对接APns消息推送(基于HTTP/2协议)】

Java使用pushy(com.eatthepath)对接APns消息推送(基于HTTP/2协议) 需要IOS开发提供的信息 1.推送证书,.p8格式的文件 2.bundleId 3.keyId 4.teamId MAVEN依赖 <dependency><groupId>com.eatthepath</groupId><artifactId>pushy</artifactId>…

HTAP 简介

2019独角兽企业重金招聘Python工程师标准>>> HTAP的定义 数据库系统一般可以按照负载类型分成操作型数据库(Operational Support System)和决策型数据库(Decision Support System)。操作型数据库主要用于应对日常流水类业务,主要是面向消费者类的业务;决策型数…

爬取twitter数据--使用twint

最近因为实验验证的需要&#xff0c;想要爬取推特的数据&#xff0c;首先想到的是通过推特官方的开发者计划拿到key然后直接爬取&#xff0c;连接如下&#xff1a; twitter myapp 但是问题就在于&#xff0c;这玩意我用两个号申请都被拒绝了&#xff0c;据说是86的号码被拒就是…

tweepy抓取Twitter数据

Tweepy是Twitter官方提供的Python第三方开发库&#xff0c;简单好用易学高效&#xff01; 安装的流程很简单&#xff0c;如果你和我一样的win10_64bit用户&#xff0c;如果你配置了pip管理器&#xff0c;在你的终端里输入 >> pip install tweepy 就会自动安装好了 我们先…

【PWA学习】4. 使用 Push API 实现消息推送

引言 在接下来的内容里&#xff0c;我们会探究 PWA 中的另一个重要功能——消息推送与提醒(Push & Notification)。这个能力让我们可以从服务端向用户推送各类消息并引导用户触发相应交互 Web Push 效果 Push API 和 Notification API 其实是两个独立的技术&#xff0c;完全…

TWAMP 协议

使用标准协议测量IP网络性能始终是一项挑战。IP发明者曾作为TCP/IP协议套件的一部分提供了一些工具,如Internet控制消息协议(ICMP)Ping、Traceroute和用户数据报协议(UDP)Echo。但是,这些工具并不是为执行总体性能测试而准备的,而是设计用于简单排查IP网络故障。因此,企…