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

深入解析 Java ClassLoader:揭开 JVM 动态加载的神秘面纱

大家好,这里是架构资源栈!点击上方关注,添加“星标”,一起学习大厂前沿架构!

Java 之所以能实现“一次编写,到处运行”,很大程度得益于其虚拟机(JVM)强大的跨平台能力。而在 JVM 的核心组件中,ClassLoader(类加载器) 扮演着至关重要的角色。理解 Java 的类加载机制,不仅有助于掌握底层原理,还能提升开发调试、性能调优以及安全控制的能力。

本文将带你系统了解 Java 中类是如何一步步被加载、链接并初始化的,并通过实例剖析动态加载和绑定的实现原理。


什么是 Java ClassLoader?

Java 中的 ClassLoader 负责在运行时动态加载类。当某个类被首次使用时(如实例化、调用静态方法或访问静态变量),JVM 会委托 ClassLoader 去加载该类的字节码,并将其转化为内存中的 Class 对象。

Java 默认提供三种内建的类加载器,构成一个层级结构

  • Bootstrap ClassLoader(引导类加载器)

    • 由 C++ 实现,是所有 ClassLoader 的根。
    • 负责加载核心类库,如 rt.jar 中的类。
  • Platform ClassLoader(平台类加载器)

    • 曾被称为 Extension ClassLoader。
    • 加载 lib/ext 目录下的扩展类,如 javax.* 开头的包。
  • Application ClassLoader(系统类加载器)

    • 加载用户应用指定的 classpath 路径下的类或 jar 包。

ClassLoader 层级结构与双亲委派模型

Java 的类加载器遵循双亲委派模型(Parent Delegation Model):

Bootstrap ClassLoader↑ delegates to
Platform ClassLoader↑ delegates to
Application ClassLoader

也就是说,当一个类加载器接到加载请求时,首先会将请求委托给它的父加载器,只有在父加载器无法完成加载时,当前加载器才会尝试自己去加载。

为什么要使用双亲委派?

  • 避免重复加载:确保每个类只被加载一次。
  • 保证核心类一致性:如 java.lang.Object 始终由引导类加载器加载。
  • 提高安全性:防止用户自定义类覆盖核心类。

JVM 类加载的三大阶段

Java 的类加载过程可分为三个阶段:加载(Loading)→ 链接(Linking)→ 初始化(Initialization)

类加载阶段

1. 加载(Loading)

  • ClassLoader 从文件系统或网络中读取 .class 字节码。
  • 解析类元数据(类名、父类、接口、字段、方法等)。
  • 在方法区存储类的结构信息。
  • 在堆中创建对应的 Class 对象。

✅ 类的加载是惰性的,即只有在第一次被使用时才会触发加载。

2. 链接(Linking)

将类准备好用于执行,分三步:

  • 验证(Verification):确保字节码合法、符合 JVM 规范。
  • 准备(Preparation):为静态字段分配内存并设置默认值。
  • 解析(Resolution):将符号引用(Symbolic Reference)转换为直接引用。

☝️ 注意:解析可在链接阶段完成,也可在首次访问时延迟进行(懒加载)。

3. 初始化(Initialization)

  • 对静态变量赋初始值。
  • 执行静态代码块。
static int count = 100; // 会覆盖准备阶段的默认值 0
static {System.out.println("类被初始化了");
}

JVM 保证初始化过程是线程安全的,只执行一次。


Java 的动态加载与绑定

动态加载(Dynamic Loading)

Java 支持在运行时根据需要加载类,比如使用反射:

Class<?> clazz = Class.forName("com.example.MyClass");
Object obj = clazz.getDeclaredConstructor().newInstance();
if (someCondition) {try {Class<?> clazz = Class.forName("com.example.MyClass");Object instance = clazz.getDeclaredConstructor().newInstance();// 使用 instance 对象} catch (Exception e) {e.printStackTrace();}
}

动态绑定(Dynamic Binding)

JVM 在运行时根据实际对象的类型决定调用哪个方法,这是多态的核心。

class Animal {void sound() { System.out.println("动物叫"); }
}class Dog extends Animal {void sound() { System.out.println("狗叫"); }
}public class Example {public static void main(String[] args) {Animal a = new Dog();a.sound(); // 输出:"狗叫"}
}

动态特性:优势与代价

特性优势代价
动态加载实现插件化架构存在类加载性能开销
动态绑定实现运行时多态JVM 需额外决策

✅ 动态特性是 Java 实现扩展性和灵活性的关键所在。


接口驱动的运行时决策

结合接口与反射,可以在运行时决定具体实现:

public interface PaymentService {void pay();
}public class CreditCardPayment implements PaymentService {public void pay() { System.out.println("信用卡支付"); }
}public class PayPalPayment implements PaymentService {public void pay() { System.out.println("PayPal 支付"); }
}public class PaymentProcessor {public static void main(String[] args) throws Exception {String paymentType = "CreditCardPayment"; // 可以来自配置文件或用户输入PaymentService paymentService = (PaymentService)Class.forName("com.example." + paymentType).getDeclaredConstructor().newInstance();paymentService.pay();  // 输出:"信用卡支付"}
}

Java 对象布局揭秘:JOL 工具介绍

JVM 中的对象在内存中是如何排布的?这就是 [JOL (Java Object Layout)] 提供的功能。

对象一般包含三部分:

  • 对象头:存储哈希码、GC 信息、锁标志等。
  • 实例字段:对象真正的数据部分。
  • 对齐填充:为了内存对齐,通常为 8 字节对齐。

如何使用 JOL?

引入依赖:

dependencies {implementation 'org.openjdk.jol:jol-core:0.16'
}

示例代码:

import org.openjdk.jol.info.ClassLayout;class SimpleObject {int intField;long longField;byte byteField;Object refField;
}public class JolTest {public static void main(String[] args) {SimpleObject obj = new SimpleObject();System.out.println("Before hashCode():");System.out.println(ClassLayout.parseInstance(obj).toPrintable());obj.hashCode(); // 会影响 Mark Word 中的内容System.out.println("After hashCode():");System.out.println(ClassLayout.parseInstance(obj).toPrintable());}
}

运行结果展示了对象布局的变化,尤其是 Mark Word 部分在调用 hashCode() 前后的差异。

JOL输出示例


对象头详解

  • Mark Word:保存对象的哈希值、GC 年龄、锁信息等,是对象头中最重要的部分之一。
  • Klass Pointer:指向类的元数据(在方法区中),用于对象定位其类定义。

总结

ClassLoader 构成了 Java 程序运行的骨架,通过按需加载、链接与初始化类,实现了平台无关性与高扩展性的完美结合。

掌握 Java 类加载机制,不仅能优化系统性能、解决类冲突问题,还能让开发者具备操作 JVM 的底层能力,从而从“写代码的人”跃升为真正理解平台的人。


如需持续关注 JVM 深度解析、Java 性能优化等内容,欢迎点赞、关注、收藏支持!

转自:https://mp.weixin.qq.com/s/lgRsmMcfdzUIK3LKWhVmzQ

相关文章:

深入解析 Java ClassLoader:揭开 JVM 动态加载的神秘面纱

大家好&#xff0c;这里是架构资源栈&#xff01;点击上方关注&#xff0c;添加“星标”&#xff0c;一起学习大厂前沿架构&#xff01; Java 之所以能实现“一次编写&#xff0c;到处运行”&#xff0c;很大程度得益于其虚拟机&#xff08;JVM&#xff09;强大的跨平台能力。…...

CICD实战(一) -----Jenkins的下载与安装

服务器IPJenkins192.168.242.153gitlab192.168.242.154 1、安装工具&#xff08;可选&#xff0c;如果有就不需要安装&#xff09; sudo yum install wget net-tools 2、关闭防火墙 #关闭防火墙(如果是云服务器部署,去安全组放通对应的端口即可) systemctl stop firewalld …...

【.net core】.KMZ文件解压为.KML文件并解析为GEOJSON坐标数据集。附KML处理多线(LineString)闭环问题

通过使用ZipFile解压KMZ文件&#xff0c;获取其中的KML文件&#xff0c;并解析KML文件&#xff0c;输出解析后的坐标数据集。 KML文件:地理信息的标准格式 解析后的坐标数据集输出格式&#xff08;GEOJSON坐标数据集&#xff09;&#xff1a;[[[经度,纬度],[经度,纬度]]] 解…...

Python打卡训练营day46——2025.06.06

知识点回顾&#xff1a; 不同CNN层的特征图&#xff1a;不同通道的特征图什么是注意力&#xff1a;注意力家族&#xff0c;类似于动物园&#xff0c;都是不同的模块&#xff0c;好不好试了才知道。通道注意力&#xff1a;模型的定义和插入的位置通道注意力后的特征图和热力图 …...

网络资源缓存

前端性能优化是提升用户体验和页面响应速度的关键&#xff0c;可以从 网络优化、资源优化、缓存优化 三个方面系统地进行。以下是详细说明&#xff1a; 一、网络优化&#xff08;减少请求数、降低延迟、提升加载速度&#xff09; 减少 HTTP 请求数量 合并请求&#xff08;CSS…...

Linux中 SONAME 的作用

🧠 一、从 -lexample 到 SONAME ✅ 假设你有以下文件结构: /libexample.so → libexample.so.1 /libexample.so.1 → libexample.so.1.0.0 /libexample.so.1.0.0 # SONAME: libexample.so.1/libexample.so.2 → libexample.so.2.0.0 /libexample.so.2.0…...

Devops系列---python基础篇二

1、列表 1.1 概念 格式&#xff1a; 名称 [ “元素1”,“元素2”,…] #定义一个列表 computer ["主机","键盘","显示器","鼠标"]类型方法用途查index(“元素”)查看元素索引位置count(“元素”)统计元素出现的次数reverse()倒序排…...

自定义事件wpf

// 自定义控件 public class MyCustomControl : Control { public static readonly RoutedEvent MyCustomEvent EventManager.RegisterRoutedEvent( "MyCustom", RoutingStrategy.Bubbling, typeof(RoutedEventHandler), typeof(MyCustomControl) ); public event R…...

​​TLV4062-Q1​​、TLV4082-Q1​​迟滞电压比较器应用笔记

文章目录 主要作用应用场景关键优势典型应用示意图TLV4062-Q1 和 TLV4082-Q1 的主要作用及应用场景如下: 主要作用 精密电压监测:是一款双通道、低功耗比较器,用于监测输入电压是否超过预设阈值。 集成高精度基准电压源(阈值精度1%),内置60mV迟滞功能,可避免因噪声导致的…...

C++.OpenGL (3/64)着色器(Shader)深入

着色器(Shader)深入 着色器核心概念 #mermaid-svg-xC0jTt9mJWGVa7yE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-xC0jTt9mJWGVa7yE .error-icon{fill:#552222;}#mermaid-svg-xC0jTt9mJWGVa7yE .error-text{fi…...

DHCP介绍

DHCP介绍 1 DHCP简述2 DHCP协议分析2.1 主要流程2.2 DHCP全部报文介绍2.3 IP租用更新报文2.4 DHCP协议抓包分析 3 DHCP应用3.1 DNSmasq参数配置3.2 DNSmasq框架代码3.2.1 创建socket监听67端口3.2.2 监听67端口3.2.3 处理DHCP请求 3.3 DNSmasq模块排障方法 4 常见问题排查4.1 问…...

李沐《动手学深度学习》d2l安装教程

文章目录 最新回答报错提醒安装对应版本安装C工具和Windows SDK 最新回答 安装旧版本即可 pip install d2l0.17.0 WARNING: Ignoring invalid distribution -pencv-python (e:\python3.10\lib\site-packages) Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple C…...

[蓝桥杯]耐摔指数

耐摔指数 题目描述 X 星球的居民脾气不太好&#xff0c;但好在他们生气的时候唯一的异常举动是&#xff1a;摔手机。 各大厂商也就纷纷推出各种耐摔型手机。X 星球的质监局规定了手机必须经过耐摔测试&#xff0c;并且评定出一个耐摔指数来&#xff0c;之后才允许上市流通。…...

深入理解数字音频:采样率、位深与量化

在当今数字时代&#xff0c;音频技术已经渗透到我们生活的方方面面——从流媒体音乐到视频会议&#xff0c;从播客到智能家居。但你是否曾好奇过&#xff0c;这些美妙的声音是如何被捕捉、存储并在数字世界中重现的&#xff1f;本文将带你深入了解数字音频的核心概念&#xff0…...

2024年第十五届蓝桥杯青少Scratch初级组-国赛—画矩形

2024年第十五届蓝桥杯青少Scratch初级组-国赛—画矩形 题目点下方&#xff0c;支持在线编程&#xff0c;在线获取源码和素材&#xff5e; 画矩形_scratch_少儿编程题库学习中心-嗨信奥 程序演示可点下方&#xff0c;支持源码获取&#xff5e; 画矩形-scratch作品-少儿编程题库…...

java面试场景题: 设计⼀个微博系统

微博系统设计指南&#xff1a;从理论到实践 系统设计考察的核心能力 系统设计面试模拟真实工作场景&#xff0c;候选人需与面试官协作解决模糊问题。关键在于沟通、分析和权衡能力&#xff0c;而非追求完美方案。面试官关注思考过程&#xff0c;而非最终答案。 常见误区与改…...

市面上哪款AI开源软件做ppt最好?

市面上哪款AI开源软件做ppt最好&#xff1f; aippt&#xff1a;AiPPT - 全智能 AI 一键生成 PPT 网站形式&#xff0c;需要注册 ai to pptx &#xff1a;SmartSchoolAI/ai-to-pptx: 前端后端同时开源。 Ai-to-pptx是一个使用AI技术(DeepSeek)制作PPTX的助手&#xff0c;支持在…...

JMM初学

文章目录 1,线程间的同步和通信1.1, 共享内存并发模型 (Shared Memory Model)线程通信机制线程同步机制特点 1.2, 消息传递并发模型 (Message Passing Model)线程通信机制线程同步机制特点 适用场景对比 2,Java内存模型JMM2.0,Java内存模型的基础&#xff08;1&#xff09;内存…...

transformer和 RNN以及他的几个变体区别 改进

Transformer、RNN 及其变体&#xff08;LSTM/GRU&#xff09;是深度学习中处理序列数据的核心模型&#xff0c;但它们的架构设计和应用场景有显著差异。以下从技术原理、优缺点和适用场景三个维度进行对比分析&#xff1a; 核心架构对比 模型核心机制并行计算能力长序列依赖处…...

构建云原生安全治理体系:挑战、策略与实践路径

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;从传统安全走向“云原生安全” 随着企业 IT 架构从传统单体系统向容器化、微服务和云原生平台转型&#xf…...

vue-print-nb 打印相关问题

一、背景与解决方案 1、ElementUI表格打印通病&#xff0c;均面临边框丢失、宽度超出问题&#xff1a;相关解决代码有注释&#xff1b; 2、大多数情况下不会打印页眉页脚的日期、网址、未配置popTitle显示的undefined&#xff1a;相关解决代码有注释&#xff1b; 3、打印预览页…...

vcs仿真产生fsdb波形的两种方式

目录 方法一&#xff1a; 使用verilog自带的系统函数 方法二&#xff1a; 使用UCLI command 2.1 需要了解什么是vcs的ucli&#xff0c;怎么使用ucli&#xff1f; 2.2 使用ucli dump波形的方法 使用vcs仿真产生fsdb波形有两种方式&#xff0c;本文参考《vcs user guide 20…...

每日算法 -【Swift 算法】三数之和

Swift&#xff5c;三数之和&#xff08;3Sum&#xff09;详细题解 注释 拓展&#xff08;LeetCode 15&#xff09; ✨题目描述 给你一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a, b, c&#xff0c;使得 a b c 0。请你找出所有和为 0 且不重…...

Go语言底层(三): sync 锁 与 对象池

1. 背景 在并发编程中&#xff0c;正确地管理共享资源是构建高性能程序的关键。Go 语言标准库中的 sync 包提供了一组基础而强大的并发原语&#xff0c;用于实现安全的协程间同步与资源控制。本文将简要介绍 sync 包中常用的类型和方法: sync 锁 与 对象池&#xff0c;帮助开发…...

登高架设作业操作证考试:理论题库高频考点有哪些?

一、安全基础知识 法律法规 《安全生产法》《特种作业人员安全技术培训考核管理规定》中关于登高作业的强制性要求&#xff08;如持证上岗、培训时限等&#xff09;。 事故责任划分&#xff1a;未系安全带、无监护作业等违规行为的法律后果。 个人防护 安全带使用标准&#…...

2025年06月06日Github流行趋势

项目名称&#xff1a;agent-zero 项目地址url&#xff1a;https://github.com/frdel/agent-zero项目语言&#xff1a;Python历史star数&#xff1a;8958今日star数&#xff1a;324项目维护者&#xff1a;frdel, 3clyp50, linuztx, evrardt, Jbollenbacher项目简介&#xff1a;A…...

华为云CentOS配置在线yum源,连接公网后,逐步复制粘贴,看好自己对应的版本即可,【新手必看】

华为云镜像源配置 YUM 源的详细步骤&#xff1a; 1. 备份原有的 YUM 源配置文件 在修改 YUM 源之前&#xff0c;建议备份原有的配置文件。通常&#xff0c;YUM 源的配置文件位于 /etc/yum.repos.d/ 目录下。例如&#xff0c;备份 CentOS 的默认 YUM 源配置文件&#xff1a; …...

http头部注入攻击

1.HTTP请求的组成部分​​ HTTP(HyperText Transfer Protocol)请求由 ​​请求行(Request Line)、请求头(Headers)、空行(Blank Line)和请求体(Request Body)​​ 组成。具体结构如下: ​​1. 请求行(Request Line)​​ 请求行是HTTP请求的第一行,包含三个部分…...

三类 Telegram 账号的风控差异分析与使用建议

在使用 Telegram 过程中&#xff0c;很多用户会遇到账号被限制、封禁、加群失败等问题。除了操作行为外&#xff0c;账号本身的注册方式、活跃时间、环境匹配程度也会直接影响风控等级。 本篇文章从账号风控角度出发&#xff0c;分析三类常见 Telegram 账号的特点与适用环境&am…...

Matlab | matlab中的点云处理详解

点云处理 ⚙️ **一、点云基础操作**🧹 **二、点云预处理**📊 **三、特征提取与分析**🔄 **四、点云配准(对齐点云)**🔷 **五、三维重建与应用**⚡️ **六、高级功能与性能优化**💎 **七、实战技巧与参数调优**📚 **学习资源**MATLAB 的点云处理能力主要依赖 Poi…...