学习笔记03——《深入理解Java虚拟机(第三版)》类加载机制知识总结与面试核心要点
《深入理解Java虚拟机(第三版)》类加载机制知识总结与面试核心要点
一、章节核心脉络
核心命题:JVM如何将.class文件加载到内存并转换为运行时数据结构?
核心流程:加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载
三大核心机制:
- 类加载过程(双亲委派模型)
- 类初始化触发条件(主动引用 vs 被动引用)
- 类加载器体系(Bootstrap、Extension、Application、自定义加载器)
二、类加载机制深度解析
1. 类加载生命周期
| 阶段 | 关键行为 | 示例/注意事项 |
|---|---|---|
| 加载 | 1. 获取.class二进制流 2. 转换为方法区数据结构 3. 生成 Class对象 | 可从ZIP包、网络、动态代理等来源加载 |
| 验证 | 文件格式验证、元数据验证、字节码验证、符号引用验证 | 防止恶意代码注入(如魔数CAFE BABE验证) |
| 准备 | 为类变量(static变量)分配内存并赋初始值(零值) | static int x=5;在此阶段x=0 |
| 解析 | 将符号引用转换为直接引用(方法、字段、接口方法) | 可能触发其他类的加载(如父类或接口) |
| 初始化 | 执行<clinit>()方法(静态变量赋值 + static块) | 多线程环境下JVM保证同步执行 |
类初始化触发条件(主动引用):
new、getstatic、putstatic、invokestatic指令- 反射调用(
Class.forName()) - 子类初始化触发父类初始化
- 主类(包含main方法的类)
被动引用示例(不会触发初始化):
- 通过子类访问父类静态字段
- 通过数组定义引用类(
MyClass[] arr = new MyClass[10];) - 访问类的
final static常量(编译期优化)
2. 类加载器体系与双亲委派模型
(1) 类加载器分类
| 类加载器 | 加载路径 | 实现语言 | 是否可自定义 |
|---|---|---|---|
| Bootstrap ClassLoader | jre/lib目录(rt.jar等核心库) | C++ | ❌ |
| Extension ClassLoader | jre/lib/ext目录 | Java | ❌ |
| Application ClassLoader | CLASSPATH环境变量或用户类路径 | Java | ❌ |
| Custom ClassLoader | 自定义路径(网络、加密文件等) | Java | ✅ |
(2) 双亲委派模型工作流程
核心规则:
- 收到类加载请求后,优先委派父加载器处理
- 所有父加载器无法完成时,才由自己加载
设计优势:
- 避免重复加载(如核心类
java.lang.Object) - 安全防护(防止用户自定义类冒充核心类)
破坏双亲委派的场景:
- SPI机制(JDBC驱动加载,使用线程上下文类加载器
ThreadContextClassLoader) - OSGi模块化热部署
- Tomcat容器隔离(不同Web应用使用独立类加载器)
3. 自定义类加载器实现
关键步骤:
- 继承
ClassLoader类 - 重写
findClass()方法(非loadClass(),避免破坏双亲委派) - 通过
defineClass()将字节码转换为Class对象
代码示例:
public class MyClassLoader extends ClassLoader { @Override protected Class<?> findClass(String name) { byte[] classData = loadClassData(name); return defineClass(name, classData, 0, classData.length); } // 从自定义路径加载字节码...
}
三、高频面试问题与答案要点
1. 类加载过程与双亲委派模型
问题:描述类加载过程,双亲委派模型的作用及如何打破?
答:
- 过程:加载→验证→准备→解析→初始化(重点说明各阶段核心任务)
- 双亲委派作用:避免重复加载、保证核心类安全
- 打破方式:重写
loadClass()方法、使用线程上下文类加载器(如JDBC SPI)
2. ClassNotFoundException vs NoClassDefFoundError
问题:二者的区别是什么?
答:
- ClassNotFoundException:类加载器在类路径中找不到目标类(如
Class.forName()失败) - NoClassDefFoundError:JVM在运行时找不到类的定义(编译时存在,运行时缺失或初始化失败)
3. 类初始化顺序问题
问题:父类和子类的静态代码块、构造代码块执行顺序?
答:
- 父类静态块 → 子类静态块
- 父类构造代码块 → 父类构造函数
- 子类构造代码块 → 子类构造函数
4. Tomcat类加载机制
问题:Tomcat如何实现不同Web应用隔离?
答:
- 每个Web应用使用独立的
WebappClassLoader - 优先加载
/WEB-INF/classes和/WEB-INF/lib下的类 - 通过破坏双亲委派实现应用间类隔离
5. SPI机制原理
问题:JDBC如何通过SPI加载驱动?
答:
- 核心接口由Bootstrap加载器加载(如
java.sql.Driver) - 具体实现类由线程上下文类加载器加载(如
com.mysql.cj.jdbc.Driver)
四、实战问题排查与工具
1. 类冲突排查
现象:java.lang.LinkageError或方法调用不一致
工具:
-verbose:class参数打印类加载日志jcmd <pid> VM.classloader_stats查看类加载器统计
2. 热替换实现原理
方案:自定义类加载器每次加载新版本类,旧版本类无法卸载(PermGen/Metaspace限制)
五、扩展思考
- 模块化系统影响:JDK9+的模块化(Jigsaw)如何改变类加载机制?
- 模块化路径取代类路径
- 新增
Layer概念实现模块隔离
- 动态加载应用:如何实现类似Spring的Bean动态加载?
学习建议:结合javap -c反编译工具观察<clinit>和<init>方法,通过Arthas等工具动态跟踪类加载过程。
相关文章:
学习笔记03——《深入理解Java虚拟机(第三版)》类加载机制知识总结与面试核心要点
《深入理解Java虚拟机(第三版)》类加载机制知识总结与面试核心要点 一、章节核心脉络 核心命题:JVM如何将.class文件加载到内存并转换为运行时数据结构? 核心流程:加载 → 验证 → 准备 → 解析 → 初始化 → 使用 →…...
w227springboot旅游管理系统设计与实现
🙊作者简介:多年一线开发工作经验,原创团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文…...
漏洞文字版表述一句话版本(漏洞危害以及修复建议),通常用于漏洞通报中简洁干练【持续更新中】
漏洞文字版表述一句话版本(漏洞危害以及修复建议) SQL注入漏洞 危害描述: SQL注入漏洞允许攻击者通过构造恶意的SQL语句,绕过应用程序的安全检查,直接访问或操作数据库。这可能导致数据泄露、数据篡改、甚至数据库被删除等严重后果…...
项目——仿RabbitMQ实现消息队列
1.项目介绍 曾经在学习Linux的过程中,我们学习过阻塞队列 (BlockingQueue) 。 当时我们说阻塞队列最大的用途, 就是用来实现生产者消费者模型。 生产者消费者模型是后端开发的常用编程方式, 它存在诸多好处: 解耦合支持并发支持忙闲不均削峰…...
嵌入式硬件篇---滤波器
文章目录 前言一、模拟电子技术中的滤波器1. 基本概念功能实现方式 2. 分类按频率响应低通滤波器高通滤波器带通滤波器带阻滤波器 按实现方式无源滤波器有源滤波器 3. 设计方法巴特沃斯滤波器(Butterworth)切比雪夫滤波器(Chebyshevÿ…...
JAVA最新版本详细安装教程(附安装包)
目录 文章自述 一、JAVA下载 二、JAVA安装 1.首先在D盘创建【java/jdk-23】文件夹 2.把下载的压缩包移动到【jdk-23】文件夹内,右键点击【解压到当前文件夹】 3.如图解压会有【jdk-23.0.1】文件 4.右键桌面此电脑,点击【属性】 5.下滑滚动条&…...
《筑牢元宇宙根基:AI与区块链的安全信任密码》
在科技浪潮汹涌澎湃的当下,元宇宙已不再是科幻作品中的遥远构想,而是逐渐步入现实,成为人们热议与探索的前沿领域。从沉浸式的虚拟社交,到创新的数字经济模式,元宇宙的发展前景广阔,潜力无限。但要让元宇宙…...
云原生周刊:云原生和 AI
开源项目推荐 FlashMLA DeepSeek 于北京时间 2025 年 2 月 24 日上午 9 点正式开源了 FlashMLA 项目。FlashMLA 是专为 NVIDIA Hopper 架构 GPU(如 H100、H800)优化的高效多头潜在注意力(MLA)解码内核,旨在提升大模型…...
rust笔记9-引用与原始指针
Rust 中的指针类型和引用类型是理解其内存管理机制的关键部分。& 引用和 * 原始指针在底层原理上确实都可以认为是指针,它们都存储了某个内存地址,并指向该地址处的数据。然而,它们在安全性、使用方式和编译器支持上有显著的区别。下面我会详细解释它们的异同点,帮助你…...
信而泰CCL仿真:解锁AI算力极限,智算中心网络性能跃升之道
引言 随着AI大模型训练和推理需求的爆发式增长,智算中心网络的高效性与稳定性成为决定AI产业发展的核心要素。信而泰凭借自主研发的CCL(集合通信库)评估工具与DarYu-X系列测试仪,为智算中心RoCE网络提供精准评估方案,…...
本地部署AI模型 --- DeepSeek(二)---更新中
目录 FAQ 1.Failed to load the model Exit code: 18446744072635812000 FAQ 1.Failed to load the model Exit code: 18446744072635812000 问题描述: 🥲 Failed to load the model Error loading model. (Exit code: 18446744072635812000). Unkn…...
c++类知识点复习与总结
类 c 是一种人机交互的面向对象的编程语言,面向对象思想主要体现在 类 上。 类是具有相同属性和相同行为的对象的集合, 具有封装,继承,多态的特性。 类的定义 class 类名 { }; 封装 例如:人就是一种类…...
C++的allactor
https://zhuanlan.zhihu.com/p/693267319 1 双层内存配置器 SGI设计了两层的配置器,也就是第一级配置器和第二级配置器。同时为了自由选择,STL又规定了 __USE_MALLOC 宏,如果它存在则直接调用第一级配置器,不然则直接调用第二级配…...
【2025深度学习环境搭建-2】pytorch+Docker+VS Code+DevContainer搭建本地深度学习环境
上一篇文章:【2025深度学习环境搭建-1】在Win11上用WSL2和Docker解锁GPU加速 先启动Docker!对文件内容有疑问,就去问AI 一、用Docker拉取pytorch镜像,启动容器,测试GPU docker pull pytorch/pytorch:2.5.0-cuda12.4…...
在CentOS 7上安装和使用Spleeter音频分离工具的详细步骤
在音频处理领域,Spleeter是一款优秀的开源工具,能够帮助用户轻松实现音频文件中人声和背景音的分离。本文将详细介绍在CentOS 7系统上安装和配置Spleeter的步骤,以及如何使用Spleeter进行音频分离。 准备环境: 在开始安装Spleeter之前&…...
【1】VS Code 新建上位机项目---C#基础语法
VS Code 新建上位机项目---C#基础语法 1 基本概念1.1 准备工具1.2 新建项目2 C#编程基础2.1 命名空间和类2.2 数据类型2.3 控制台输入输出2.3.1 输入输出: write 与 read2.3.2 格式化 : string.Foramt() 与 $2.3.3 赋值与运算2.4 类型转换2.4.1 数值类型之间的转换:(int)2.4…...
电脑经常绿屏(蓝屏)怎么办(解决方法)?
一、排查系统与驱动问题 进入安全模式修复系统 强制重启电脑 3 次触发恢复环境,选择 疑难解答 > 高级选项 > 启动设置 > 重启,按 F5 或 5 进入带网络连接的安全模式3。 在安全模式下,尝试卸载最近安装的软件或更新,尤其…...
clickhouse--本地表和分布式表,副本机制,分片集群
1、本地表和分布式表 ck的表分为两种: 分布式表 一个逻辑上的表,可以理解为数据库中的视图,一般查询都查询分布式表。分布式表引擎会将我们的查询请求路由本地表进行查询,然后进行汇总最终返回给用户。本地表 实际存储数据的表。 …...
react hook useReducer
useReducer useReducer 是 React 中用于状态管理的 Hook,与 useState 不同,它更适合处理复杂的状态逻辑. const [state, dispatch] useReducer(reducer, initialArg, init?) reducer 是一个处理函数,用于更新状态, reducer 里面包含了两个…...
告别阻塞,迎接高效:掌握 AsyncIOScheduler 实现异步任务调度
前言 时间在编程中是宝贵的,直接关联到效率与灵活性,尤其在异步编程里,如何优雅地管理定时任务简直是一门“艺术”。如果你还在用 time.sleep() 来控制延时任务,恐怕你早已体会过它的“痛苦”:程序卡住、线程阻塞、性能急剧下滑。想象一下,你的程序如同一个永远无法按时…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
2025-05-08-deepseek本地化部署
title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek:小白也能轻松搞定! 如何给本地部署的 DeepSeek 投喂数据,让他更懂你 [实验目的]:理解系统架构与原…...
