Java类加载

Java类加载机制是Java虚拟机(JVM)的一个核心组成部分,它负责将Java类从不同的数据源(如本地文件系统、网络等)加载到JVM中,并为之生成对应的java.lang.Class对象。理解Java类加载机制对于深入理解Java运行时的行为、解决类加载相关的问题以及进行高级框架开发都具有重要意义。

类加载的生命周期

在这里插入图片描述

// 加载
硬盘查找并通过IO读入字节码文件(Java编译过的.class文件),这里是懒加载,只有使用时才会加载(通过类加载器),加载会在内存中(JVM的元空间)生成一个代表这个类的Class对象.
// 验证
校验字节码文件的正确性.比如格式、jdk版本号等.
// 准备
为类的静态变量分配内存,并将其初始化为默认值(例如ingt默认值0)
// 解析
将类中的符号引用转换为直接引用。
这里的'符号引用'指的是类文件常量池中的各种引用,它们以一种抽象的方式引用其他类、接口、字段和方法,而这些引用在类文件中并不直接指向目标的内存地址。当类被加载解析时需要将这些'符号引用'转化为'直接引用'.
// 初始化
初始化阶段是执行类构造器<clinit>()方法的过程。这个方法由编译器自动合成,包含了类变量的赋值操作和静态代码块中的语句。
// 使用
在完成了加载、链接(验证、准备、解析)和初始化之后,类就可以被程序使用了,比如创建类的实例、访问类的静态变量和调用类的静态方法等。
// 卸载
类在长时间没有被使用且没有任何引用时,JVM会考虑将其卸载,释放掉占用的资源.

类加载器

Java虚拟机通过类加载器来实现类的加载。Java中的类加载器通常分为以下几种:

// 启动类加载器(Bootstrap ClassLoader)
它是虚拟机自带的类加载器,负责加载JAVA_HOME/lib目录中的类库。
// 扩展类加载器(Extension ClassLoader)
它负责加载JAVA_HOME/lib/ext目录中的类库。
// 应用程序类加载器(Application ClassLoader)
它负责加载用户类路径(Classpath)上所指定的类库。
// 自定义类加载器
用户还可以通过继承java.lang.ClassLoader类的方式来创建自定义的类加载器。

双亲委派机制

双亲委派机制(Parent Delegation Model)是Java类加载器(ClassLoader)采用的一种类加载机制。在这种机制下,类加载器在尝试加载一个类时,会先委托给其父加载器进行加载,每一级加载器都是如此,直到顶层的启动类加载器(Bootstrap ClassLoader)。只有当父加载器无法完成这个加载请求(它在自己的搜索范围内没有找到所需的类)时,子加载器才会尝试自己去加载这个类。

在这里插入图片描述

// 加载user.class的过程
1.首先AppClassLoader会在自己的缓存中进行判断,user.class是否已经被加载过,有就直接返回,若没有则会委托它的父类加载器ExtClassLoader.
2.ExtClassLoader也是同样的先在自己的缓存里判断是否加载过user.class,
有就直接返回,若没有则会委托它的父类加载器BootStrapClassLoader.
3.BootStrapClassLoader也是判断缓存中是否有,没有就加载,没有加载到就交给
ExtClassLoader来加载,如果还没有就轮到AppClassLoader加载.
4.最终由AppClassLoader加载user.class.
双亲委派机制的优点

1.避免类的重复加载:由于在顶层的启动类加载器开始往下查找,因此类只会被加载一次,避免了在JVM中类的多份副本。
2.保护程序安全:通过这种机制可以确保Java核心库的类型安全,防止核心API被随意篡改。

自定义类加载器

自定义类加载器需要继承 java.lang.ClassLoader 类,这个类有两个核心方法

// loadClass() 实现了双亲委派机制
protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
    
// findClass()默认实现是空方法
// 所以我们自定义类加载器主要是重写findClass方法。
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }

注:自定义类加载器默认父加载器是AppClassLoader。

打破双亲委派机制

打破双亲委派机制通常是指在自定义类加载器时,改变类加载器默认的行为,即不完全遵循双亲委派模型。在某些特定场景下,这样做是有必要的,例如Tomcat部署多个应用程序,每个程序可能依赖第三方框架的不同版本.

例子

要打破双亲委派机制,可以通过覆盖ClassLoader类的loadClass(String name, boolean resolve)方法来实现。

public class CustomClassLoader extends ClassLoader {
    @Override
    public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        // 首先,检查请求的类是否已经被加载
        Class<?> clazz = findLoadedClass(name);
        if (clazz == null) {
            try {
                // 尝试用自定义的方式加载类
                clazz = findClass(name);
            } catch (ClassNotFoundException e) {
                // 如果自定义方式失败,调用父类加载器尝试加载
                clazz = super.loadClass(name, resolve);
            }
        }
        if (resolve) {
            resolveClass(clazz);
        }
        return clazz;
    }
}

在这个例子中,CustomClassLoader首先尝试通过自定义的方式(findClass方法)来加载类,只有在失败时才回退到调用父类加载器的loadClass方法。这种方式实际上是先尝试子类加载器,然后才是父类加载器,与双亲委派模型的顺序相反。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/386305.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python中多种生成随机密码超实用实例

前言 密码是信息安全的基石&#xff0c;它用于保护我们的账户、数据和隐私。为了确保密码足够强大&#xff0c;需要生成随机密码。在本文中&#xff0c;将讨论多种Python方法&#xff0c;用于生成随机密码的实用示例和技巧。 目录 ​编辑 前言 密码生成的要求 使用secrets…

创新S3存储桶检索:Langchain社区S3加载器搭载OpenAI API

在瞬息万变的数据存储和处理领域&#xff0c;将高效的云存储解决方案与先进的 AI 功能相结合&#xff0c;为处理大量数据提供了一种变革性的方法。本文演示了使用 MinIO、Langchain 和 OpenAI 的 GPT-3.5 模型的实际实现&#xff0c;重点总结了存储在 MinIO 存储桶中的文档。 …

C++ 音视频原理

本篇文章我们来描述一下音视频原理 音视频录制原理: 下面是对这张思维导图的介绍 摄像头部分: 麦克风采集声音 摄像头采集画面 摄像头采集回来的数据可以用RGB也可以用YUV来表示 图像帧帧率 一秒能处理多少张图像 图像处理 &#xff1a;调亮度 图像帧队列 :意思是将数据取…

【51单片机】LCD1602(江科大)

1.LCD1602介绍 LCD1602(Liquid Crystal Display)液晶显示屏是一种字符型液晶显示模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符 显示容量:162个字符,每个字符为5*7点阵 2.引脚及应用电路 3.内部结构框图 屏幕: 字模库:类似于数码管的数…

【JVM篇】什么是jvm

文章目录 &#x1f354;什么是Java虚拟机&#x1f6f8;Java虚拟机有什么用&#x1f339;Java虚拟机的功能&#x1f388;Java虚拟机的组成 &#x1f354;什么是Java虚拟机 JVM指的是Java虚拟机&#xff0c;本质上是一个运行在计算机上的程序&#xff0c;可以运行 Java字节码文件…

微信小程序开发学习笔记《17》uni-app框架-tabBar

微信小程序开发学习笔记《17》uni-app框架-tabBar 博主正在学习微信小程序开发&#xff0c;希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读uni-app对应官方文档 一、创建tabBar分支 运行如下的命令&#xff0c;基于master分支在本地创建tabBar子分支&#x…

Spring Boot3自定义异常及全局异常捕获

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 前置条件 目的 主要步骤 定义自定义异常类 创建全局异常处理器 手动抛出自定义异常 前置条件 已经初始化好一个…

17 ABCD数码管显示与动态扫描原理

1. 驱动八位数码管循环点亮 1.1 数码管结构图 数码管有两种结构&#xff0c;共阴极和共阳极&#xff0c;ACX720板上的是共阳极数码管&#xff0c;低电平点亮。 1.2 三位数码管等效电路图 为了节约I/O接口&#xff0c;各个数码管的各段发光管被连在一起&#xff0c;通过sel端…

【Spring框架】Spring事务同步

目录 一、什么是Spring事务同步 二、 事务同步管理器 2.1 TransactionSynchronizationManager事务同步管理器 2.1.1 资源同步 2.1.2 事务同步 2.1.3 总结 三、事务同步管理器保障事务的原理 四、spring事务为何使用TransactionSynchronizationManager spring源码实现 …

详解CC++内存管理(new和delete)

文章目录 写在前面1. C&C内存分布2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3. C内存管理方式&#xff08;语法&#xff09;3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4. new和delete的实现原理4.1 operator new与operator delete…

企业架构师的人格特质

L - Learning 持续学习的能力A - Abstracting 概念抽象的能力C1 - Connecting 联结事物的能力C2 - Compromising 平衡折衷的能力D - Decisioning 果断决策的能力 参考文章的链接

再利用系统盘时,如何删除恢复分区(Recovery Partition)

系统盘有一个Recovery Partition&#xff0c;记录了重要的系统信息&#xff0c;不能删除。 Windows 10的 Disk Managment 不提供用户删除这个Partition的选项。 近日我插入一块原系统盘&#xff0c;Format后作为DataDisk&#xff0c;此时需要删除这块硬盘上的RecoveryPartition…

Redis中内存淘汰算法实现

Redis中内存淘汰算法实现 Redis的maxmemory支持的内存淘汰机制使得其成为一种有效的缓存方案&#xff0c;成为memcached的有效替代方案。 当内存达到maxmemory后&#xff0c;Redis会按照maxmemory-policy启动淘汰策略。 Redis 3.0中已有淘汰机制&#xff1a; noevictionall…

配置 JDK 环境变量(最简单)

前言 在通过控制台使用 javac 命令编译 &#xff0c;java 命令运行 Java 程序时&#xff0c;会出现识别不了这两个命令的情况&#xff0c;如下所示&#xff1a; 这是没有配置环境变量导致的 在控制台输入的命令&#xff0c;操作系统会去一些特定的目录中去找&#xff0c;看看是…

HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核内存管理-动态内存

目录 一、动态内存运行机制二、动态内存开发流程三、动态内存使用说明四、动态内存核心算法五、动态内存接口六、代码分析&#xff08;待续...&#xff09;坚持就有收获 一、动态内存运行机制 动态内存管理&#xff0c;即在内存资源充足的情况下&#xff0c;根据用户需求&…

漫漫数学之旅019

文章目录 经典格言数学习题古今评注名人小传 - 大卫希尔伯特 经典格言 没有人能够把我们从康托为我们创造的乐园中驱逐出去。——大卫希尔伯特&#xff08;David Hilbert&#xff09; 大卫希尔伯特&#xff0c;这位数学界的“顽皮大亨”&#xff0c;曾经用一种近乎宣誓的方式来…

更新至2022年,各省人口高质量城镇化指标体系构建原始数据(13个指标)

更新至2022年&#xff0c;各省人口高质量城镇化指标体系构建原始数据 1、时间&#xff1a;更新至2022年&#xff0c;具体每个指标时间见下文 2、来源&#xff1a;整理自国家统计局、统计年鉴 3、范围&#xff1a;31省市 4、指标&#xff1a; 2008-2022年每十万人口高等学校…

【QT+QGIS跨平台编译】之三十六:【RasterLite2+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、RasterLite2介绍二、文件下载三、文件分析四、pro文件五、编译实践一、RasterLite2介绍 RasterLite2是一个开源的轻量级栅格数据库,可以用于存储和管理各种类型的栅格数据,包括卫星遥感图像、数字高程模型等。 与传统的GIS数据存储方式不同,RasterLite2采用基…

Swift Combine 有序的异步操作 从入门到精通十二

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

零基础学编程怎么入手,中文编程工具构件箱之星空构件用法教程,系统化的编程视频教程上线

零基础学编程怎么入手&#xff0c;中文编程工具构件箱之星空构件用法教程&#xff0c;系统化的编程视频教程上线 一、前言 今天给大家分享的中文编程开发语言工具资料如下&#xff1a; 编程入门视频教程链接 http://​ https://edu.csdn.net/course/detail/39036 ​ 编程…
最新文章