类加载器加载过程
今天我们就来深入了解一下Java中的类加载器以及它的加载过程。
一、什么是类加载器?
在Java中,类加载器(Class Loader)是一个非常重要的概念。它负责将类的字节码文件(.class
文件)加载到Java虚拟机(JVM)的内存中,并将其转换为一个java.lang.Class
对象。换句话说,类加载器是Java运行时环境的核心组件之一,它决定了一个类如何被加载、解析和初始化。
二、类加载器的架构
Java的类加载器采用了一种层次化的结构,通常被称为双亲委派模型。它主要由以下几种类加载器组成:
- 启动类加载器(Bootstrap Class Loader)
这是Java虚拟机自带的类加载器,它是由本地代码(通常是C语言)实现的。它的主要职责是加载Java的核心类库,比如java.lang.*
、java.util.*
等。这些类库位于JRE/lib/rt.jar
文件中。启动类加载器是类加载器层次结构的最顶层。
- 扩展类加载器(Extension Class Loader)
这个类加载器是用Java语言实现的,它负责加载Java的扩展类库。这些扩展类库通常位于JRE/lib/ext
目录下。扩展类加载器的父加载器是启动类加载器。
- 应用程序类加载器(Application Class Loader)
也被称为系统类加载器,它同样是用Java语言实现的。它的主要职责是加载应用程序的类路径(classpath
)下的类文件。应用程序类加载器的父加载器是扩展类加载器。
- 自定义类加载器(Custom Class Loader)
开发者可以根据自己的需求实现自定义的类加载器,用于加载特定的类文件。自定义类加载器的父加载器通常是应用程序类加载器,但也可以是其他类加载器。
三、类加载器的工作过程
类加载器的工作过程可以分为三个阶段:加载(Loading)、链接(Linking)和初始化(Initialization)。我们来逐一了解一下每个阶段的具体工作内容。
1.加载(Loading)
加载阶段是类加载过程的第一个阶段,主要完成以下三件事情:
• 读取字节流:类加载器会根据指定的类名(通常是全限定名),从文件系统、网络或其他存储介质中读取对应的字节码文件(.class
文件)。这个过程可以是本地文件系统的读取,也可以是从网络下载等。
• 转换为Class对象:将读取到的字节码文件转换为一个java.lang.Class
对象。这个对象是类在Java虚拟机中的唯一表示。
• 存储到方法区:将Class
对象存储到JVM的方法区(Method Area)中。方法区是JVM的内存区域之一,用于存储类的元数据、常量池等信息。
加载阶段是类加载器最直接的工作,它决定了一个类如何被加载到JVM中。
2.链接(Linking)
加载完成后,类加载器会进入链接阶段。链接阶段的主要任务是将加载的类与JVM的运行时环境进行关联。链接阶段又可以细分为三个步骤:
• 验证(Verification)
验证阶段是类加载器对字节码文件进行校验的过程。它主要检查字节码文件是否符合Java虚拟机规范,例如:类的结构是否正确、字节码指令是否合法、常量池中的符号引用是否正确等。验证阶段是保证类安全的重要环节,它可以防止恶意的字节码文件进入JVM。
• 准备(Preparation)
准备阶段主要是为类的静态变量分配内存,并设置默认初始值。例如,如果一个类中有一个静态变量int count = 0
,在准备阶段,JVM会为count
分配内存,并将其初始值设置为0
。需要注意的是,此时静态变量的值是默认初始值,而不是代码中指定的初始值。
• 解析(Resolution)
解析阶段是将类、接口、字段和方法的符号引用转换为直接引用的过程。符号引用是以字符串的形式存在的,例如java.lang.String
,而直接引用则是直接指向内存中的地址。解析阶段的目的是将符号引用替换为具体的内存地址,以便在运行时能够快速访问。
3.初始化(Initialization)
初始化阶段是类加载过程的最后一个阶段,也是类加载器真正开始执行类中的代码的阶段。在初始化阶段,JVM会执行类构造器<clinit>()
方法。<clinit>()
方法是由编译器自动收集类中的静态变量赋值操作和静态代码块中的语句组成的。初始化阶段的主要任务是为类的静态变量赋值,并执行静态代码块。
四、双亲委派模型
类加载器的双亲委派模型是Java类加载机制的核心。它的主要工作流程如下:
-
加载请求:当一个类加载器收到类加载请求时,它首先不会自己去加载这个类,而是将这个请求委派给它的父加载器。
-
逐层委派:父加载器会继续将请求委派给它的父加载器,直到最顶层的启动类加载器。如果启动类加载器可以加载这个类,就会直接加载并返回。
-
自下而上加载:如果父加载器无法加载这个类,子加载器才会尝试自己加载这个类。
双亲委派模型的好处是:
• 避免重复加载:通过委派机制,可以避免同一个类被重复加载多次。
• 保护Java核心类库的安全性:确保Java的核心类库(如java.lang.*
)始终由启动类加载器加载,防止被恶意替换。
五、总结
今天我们一起学习了Java类加载器的相关知识。我们了解了类加载器的架构,包括启动类加载器、扩展类加载器、应用程序类加载器和自定义类加载器。我们还详细探讨了类加载器的工作过程,包括加载、链接和初始化阶段。最后,我们介绍了双亲委派模型的工作原理及其重要性。
希望这些内容能够帮助你更好地理解Java类加载器的作用和机制。如果有任何疑问,欢迎随时提问!
相关文章:
类加载器加载过程
今天我们就来深入了解一下Java中的类加载器以及它的加载过程。 一、什么是类加载器? 在Java中,类加载器(Class Loader)是一个非常重要的概念。它负责将类的字节码文件(.class文件)加载到Java虚拟机&#x…...

Git基础之基本操作
文件的四种状态 Untracked:未追踪,如新建的文件,在文件夹中,没有添加到git库,不参与版本控制,通过git add将状态变为staged Unmodify:文件已入库,未修改,即版本库中的文件…...
简单的 Python 示例,用于生成电影解说视频的第一人称独白解说文案
以下是一个简单的 Python 示例,用于生成电影解说视频的第一人称独白解说文案。这个示例使用了 OpenAI 的 GPT 模型,因为它在自然语言生成方面表现出色。 实现思路 安装必要的库:使用 openai 库与 OpenAI API 进行交互。设置 API 密钥&#…...

[Pycharm]创建解释器
仅以此文章来记录自己经常脑子抽忘记的地方 有时候我们在建好了一个项目以后,想要更换解释器。以新建conda解释器为例。 一、conda解释器 1.选择setting 2.选择Add Local Interpreter 3.type选则conda。如果你之前已经有了conda环境,和我一样选择了Gen…...
在 k8s中查看最大 CPU 和内存的极限
在 Kubernetes(k8s)中,你可以从不同层面查看最大 CPU 和内存的极限,下面为你详细介绍从节点和集群层面查看的方法。 查看节点的 CPU 和内存极限 节点的 CPU 和内存极限是指单个节点上可分配的最大资源量,可通过以下几…...

【Python】为什么要写__init__.py
文章目录 PackageA(__init__特性)应该往__init__.py里放什么东西?1、包的初始化2、管理包的公共接口3、包的信息 正常我们直接导入就可以执行,但是在package的时候,有一种__init__.py的特殊存在 引入moduleA.py,执行main.py&…...
【IPFS应用开发】IPFS播放器-上传助手
本系列文章是针对 https://blog.csdn.net/weixin_43668031/article/details/83962959 内容的实现所编写的。开发经历包括思考过程、重构和推翻重来。 基于IPFS的视频播上传助手发布 起源一、优势:二、劣势:三、未来展望:上传助手Demo版本发布公告欢迎体验!立即体验:http:/…...

单细胞多数据集整合和去除批次效应教程,代做各领域生信分析
单细胞多数据集整合和去除批次效应教程 每个数据集的数据分别单独进行读取单细胞数据构建Seurat分析对象 读取各种来源的单细胞数据构建Seurat分析对象的教程 做这一步的时候可以查看我这篇写的非常详细的教程文章: 【腾讯文档】单细胞分析步骤1读取各种来源格式…...
Windows控制台函数:移动光标位置函数SetConsoleCursorPosition()
目录 什么是 SetConsoleCursorPosition? 它长什么样? 什么是 COORD? 怎么用它? 它有什么用? 跟 C 标准库有什么不一样? 注意事项 再试一个有趣的例子 什么是 SetConsoleCursorPosition?…...
MyBatis-Plus 注解大全
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 MyBatis-Plus 注解大全 MyBatis-Plus 是基于 MyBatis 的增强工具,通过注解简化了单表 CRUD 操作和复杂查询的配置。以下是常用注解的分类及详细说…...

Redis基础之基础概念
NoSQL数据库的优点 1.直接减少CPU与IO压力,是直接通过内存来读取的 2.可以直接作为缓存使用,减少IO操作 如果我们在请求中需要来传递数据,使用NoSQL可以来进行数据的直接存储和读取,从而来减少CPU与IO压力 或者是如果一些数据较为…...

Django小白级开发入门
1、Django概述 Django是一个开放源代码的Web应用框架,由Python写成。采用了MTV的框架模式,即模型M,视图V和模版T。 Django 框架的核心组件有: 用于创建模型的对象关系映射为最终用户设计较好的管理界面URL 设计设计者友好的模板…...
热图回归(Heatmap Regression)
热图回归(Heatmap Regression)是一种常用于关键点估计任务的方法,特别是在人体姿态估计中。它的基本思想是通过生成热图来表示某个关键点在图像中出现的概率或强度。以下是热图回归的主要特点和工作原理: 主要特点 热图表示: 每个关键点对应一个热图,热图中的每个像素值…...

SpringSecurity认证授权完整流程
SpringSecurity认证流程:loadUserByUsername()方法内部实现。 实现步骤: 构建一个自定义的service接口,实现SpringSecurity的UserDetailService接口。建一个service实现类,实现此loadUserByUsername方法。…...

MongoDB用户管理和复制组
用户管理 1、建用户时,use到的库就是此用户的验证库 2、登录时必须明确指定验证库才能登录 3、通常管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库 4、如果直接登录到数据库,不进行use(示例ÿ…...
【Android】setText调用导致的悬浮窗抖动问题
在Android13中,有这么一个bug,写一个可以拖到的悬浮窗,这个悬浮窗里有TextView,在拖到某个位置后,再调用TextView的setText方法,会发现出现了一个窗口动画,悬浮窗跳到了起始位置,从开…...
【从零开始学习计算机科学】数字逻辑(四)数字系统设计
【从零开始学习计算机科学】数字逻辑(四)数字系统设计 数字系统设计硬件描述语言 HDL(Hardware Description Language)Verilog HDL 的起源与发展HDL 软核、固核和硬核的重用HDL 的应用数字系统设计实现数字系统设计 一个数字集成电路的可以从不同的层次(系统级、算法级、…...

QT 作业 C++ day5
作业 代码 MyQThread.h class MyThread : public QThread {Q_OBJECT public:MyThread(QObject *parent nullptr); protected:void run() override; signals://向ui界面发送的 "复制进度" 的信号void copy_process_signal(int index); public slots:// "复…...
洛谷 P2234:[HNOI2002] 营业额统计 ← STL set
【题目来源】 https://www.luogu.com.cn/problem/P2234 【题目描述】 Tiger 最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger 拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析…...

植物神经功能紊乱检查不出来,浑身难受?
植物神经功能紊乱,又称为自主神经功能失调,是一种功能性神经症,它涉及身体多个系统的不规则反应,通常没有器质性病变作为基础。这意味着,尽管患者可能会体验到多种症状,如焦虑、紧张、心悸、疲劳、失眠等&a…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...