类加载器、双亲委派机制

news2024/11/16 14:22:48

目录

  • 1 JVM是什么
  • 2 类加载系统
    • 2.1 类的加载过程
    • 2.2 类加载器
  • 3 双亲委派机制
    • 3.1 双亲委派机制介绍
    • 3.2 双亲委派机制的优缺点
    • 3.3 自定义类加载器实现双亲委派机制

1 JVM是什么

Java Virtual Machine(Java虚拟机)是java程序实现跨平台的⼀个重要的⼯具(部件)

HotSpot VM,相信所有Java程序员都知道,它是Sun JDK和OpenJDK中所带的虚拟机,也是

⽬前使⽤范围最⼴的Java虚拟机。

只要装有JVM的平台,都可以运⾏java程序。那么Java程序在JVM上是怎么被运⾏的?

通过介绍以下JVM的三个组成部分,就可以了解到JVM内部的⼯作机制

  • 类加载系统:负责完成类的加载

  • 运⾏时数据区:在运⾏Java程序的时候会产⽣的各种数据会保存在运⾏时数据区

  • 执⾏引擎:执⾏具体的指令(代码)

2 类加载系统

类加载器是一个负责加载类的对象。ClassLoader 是一个抽象类。给定类的二进制名称,类加载器应尝试定位或生成构成类定义的数据。典型的策略是将名称转换为文件名,然后从文件系统中读取该名称的“类文件“。每个 Java 类都有一个引用指向加载它的 ClassLoader。不过,数组类不是通过 ClassLoader 创建的,而-是 JVM 在需要的时候自动创建的,数组类通过getClassLoader()方法获取 ClassLoader 的时候和该数组的元素类型的 ClassLoader 是一致的。

简单来说,类加载器的主要作用就是加载 Java 类的字节码( .class 文件)到 JVM 中(在内存中生成一个代表该类的 Class 对象

2.1 类的加载过程

⼀个类被加载进JVM中要经历哪⼏个过程

  • 加载: 通过io流的⽅式把字节码⽂件读⼊到jvm中(⽅法区)

  • 校验:通过校验字节码⽂件的头8位的16进制是否是java魔数cafebabe

  • 准备:为类中的静态部分开辟空间并赋初始化值

  • 解析:将符号引⽤转换成直接引⽤。——静态链接

  • 初始化:为类中的静态部分赋指定值并执⾏静态代码块。

类被加载后,类中的类型信息、⽅法信息、属性信息、运⾏时常量池、类加载器的引⽤等信息会被加载到元空间中。

2.2 类加载器

类是谁来负载加载的?——类加载器。不同级别的类由不同的加载器加载

  • Bootstrap ClassLoader 启动类加载器:负载加载jre/lib下的核⼼类库中的类,⽐如rt.jar、charsets.jar

    我们常用内置库 java.xxx.* 都在里面,比如java.util.、java.io.、java.nio.、java.lang.、java.sql.、java.math.

  • ExtClassLoader 扩展类加载器:负载加载jre/lib下的ext⽬录内的类

    ext 加载路径:System.getProperty("java.ext.dirs");
    
  • AppClassLoader 应⽤类加载器:负载加载⽤户⾃⼰写的类,加载当前应用 classpath 下的所有 jar 包和类。

    app 加载路径:System.getProperty("java.class.path");
    
  • ⾃定义类加载器:⾃⼰定义的类加载器,可以打破双亲委派机制。

在这里插入图片描述

由图可知,上一层加载器都会以父类的形式传入下一次加载。

3 双亲委派机制

3.1 双亲委派机制介绍

​ 当类加载进⾏加载类的时候,类的加载需要向上委托给上⼀级的类加载器,上⼀级继续向上委托,直到启动类加载器。启动类加载器去核⼼类库中找,如果没有该类则向下委派,由下⼀级扩展类加载器去扩展类库中,如果也没有继续向下委派,直到找不到为⽌,则报类找不到的异常。

双亲委派机制的流程如下:

类加载的核心代码如下:

ClassLoader.class中的

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;
        }
    }

3.2 双亲委派机制的优缺点

优点:

  • 避免重复加载:通过委派给父类加载器,可以避免同一个类被多次加载,提高了加载效率。

  • 安全性:通过双亲委派机制,核心类库由根加载器加载,可以确保核心类库的安全性,防止恶意代码替换核心类。

  • 扩展性:开发人员可以自定义类加载器,实现特定的加载策略,从而扩展Java的类加载机制。

缺点:

  • 灵活性受限:双亲委派机制对于某些特殊的类加载需求可能过于严格,限制了加载器的灵活性。

  • 破坏隔离性:如果自定义类加载器不遵循双亲委派机制,可能会破坏类加载的隔离性,导致类冲突或安全性问题。

  • 不适合动态更新:由于类加载器在加载类时会先检查父加载器是否已加载,因此在动态更新类时可能会出现问题,需要额外的处理。

总体而言,双亲委派机制通过层次结构和委派机制提供了一种有序、安全的类加载方式,但也存在一些限制和不适用的情况。

3.3 自定义类加载器实现双亲委派机制

有上面的源码可以看到,loadClass方法中会先看父类加载器中能不能调用,都不能在走findClass()方法,调用自己的加载器。可见 自定义类加载器主要就是重写findClass方法,再此类中,loadClass方法没有被重写,就会执行父类ClassLoader中的loadClass方法,只要执行的是ClassLoader中的方法,就是实现的双亲委派。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python查找替换:查找空行,空行前后添加```,```中间添加 # + 空格 + 空行后遇到的第1行文字?

初始代码 查找空行空行前后添加 中间添加 # 空行后遇到的第1行文字txt 36 96 159 8 72可以使用Python的字符串处理函数来查找并修改文本中的空行。以下是一个示例代码&#xff0c;演示如何在文本中查找空行&#xff0c;并在每个空行前后添加和一个注释&#xff1a; # 原始文本…

销售活动管理必备工具——CRM系统软件

在企业业务中&#xff0c;销售活动是实现企业业绩目标的基本单元&#xff0c;起着奠基石的作用。CRM销售管理系统是销售活动管理的必备工具&#xff0c;帮助企业更好地开展销售活动。下面来说说CRM系统如何找到并输出关键销售活动&#xff1f; 在能顺利找到并输出关键销售活动…

选刊CFP | 中科院1区TOP,IF18.6,Elsevier出版社,仅3个月录用!

【SciencePub学术】 本期推荐 部分学者论文完成后&#xff0c;选刊上犯难&#xff0c;面对纷繁复杂的期刊信息及流程&#xff0c;很难有时间和精力一一调研查看&#xff0c;小编在也经常收到此类信息&#xff0c;希望我们帮助查询期刊信息。为此&#xff0c;小编开设此专栏【选…

leetcode:455. 分发饼干(python3解法)

难度&#xff1a;简单 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff…

超详细!主流大语言模型的技术原理细节汇总!

1.比较 LLaMA、ChatGLM、Falcon 等大语言模型的细节&#xff1a;tokenizer、位置编码、Layer Normalization、激活函数等。 2. 大语言模型的分布式训练技术&#xff1a;数据并行、张量模型并行、流水线并行、3D 并行、零冗余优化器 ZeRO、CPU 卸载技术 ZeRo-offload、混合精度训…

吃透底层:从路由到前缀树

前言 今天学到关于路由相关文章&#xff0c;发现动态路由中有一个很常见的实现方式是前缀树&#xff0c;很感兴趣这个算法&#xff0c;故进行记录。 前缀树 Trie&#xff08;又被叫做字典树&#xff09;可以看作是一个确定有限状态自动机&#xff0c;尽管边上的符号一般是隐含…

Prometheus和grafana安装配置手册

1.简介 本文档为prometheus和grafana安装配置手册&#xff0c;prometheus和grafana的内容、和操作过程&#xff0c;详细介绍了服务监控配置、dashboard配置、告警配置等操作。 2.部署说明 Prometheus基于Golang编写&#xff08;需要安装&#xff09;&#xff0c;编译后的软件…

433/315无线接收芯片XL710,适合各种低功耗要求的设备等

XL710是一款高集成度、低功耗的单片ASK/OOK射频接收芯片。高频信号接收功能全部集成于片内以达到用最少的外围器件和最低的成本获得最可靠的接收效果。因此它是真正意义.上的“无线高频调制信号输入&#xff0c;数字解调信号输出”的单片接收器件。 XL710为SOP8封装&#xff0…

Python 中最常用的 4种股票价格移动平均方法(二)

一、简介 在本文中&#xff0c;我们重点关注一些小众但值得注意的移动平均方法。这些利基工具通常来自专门研究或开发用于解决非常特殊的交易场景。虽然不太主流&#xff0c;但它们提供了对市场动态的极其细致入微的见解。完整列表如下&#xff1a; 第 1 部分 — 基本技术&…

大模型部署手记(11)LLaMa2+Chinese-LLaMA-Plus-2-7B+Windows+llama.cpp+中文对话

1.简介&#xff1a; 组织机构&#xff1a;Meta&#xff08;Facebook&#xff09; 代码仓&#xff1a;GitHub - facebookresearch/llama: Inference code for LLaMA models 模型&#xff1a;LIama-2-7b-hf、Chinese-LLaMA-Plus-2-7B 下载&#xff1a;使用huggingface.co和百…

微软放大招!Bing支持DALL-E3,免费AI绘画等你来体验!

最近 OpenAI 发布了DALL-E3模型&#xff0c;出图效果和Midjourney不相上下&#xff0c;不过要使用它有些门槛&#xff0c;必须是 ChatGPT Plus 账户&#xff0c;而且还要排队&#xff0c;怎么等都等不到&#xff0c;搞得大家都比较焦虑。 不过现在微软在Bing上也支持 DALL-E3 …

Excel恢复科学技术法显示的数据

Excel中输入位数较大的数据时&#xff0c;软件会自动使用科学计数法显示。很多时候并不需要这样的计数格式&#xff0c;所以需要把它转变为普通的数字格式 操作方法 选中单元格/列/行》右键》设置单元格式 在打开的窗口中&#xff0c;切换到“数字”选项卡&#xff0c;点击“自…

第四章 图表样式美化

第四章 图表样式美化 1.图表样式概述 1.1.默认图表样式 ​ matplotlib在绘图的过程中会读取存储在本地的配置文件matplotlibrc&#xff0c;通过matplotlibrc文件中的缺省配置信息指定图表元素的默认样式&#xff0c;完成图表元素样式的初始设置。 ​ matplotlib文件包含众多…

springboot单独在指定地方输出sql

一般线上项目都是将日志进行关闭&#xff0c;因为mybatis日志打印&#xff0c;时间长了&#xff0c;会占用大量的内存&#xff0c;如果我想在我指定的地方进行打印sql情况&#xff0c;怎么玩呢&#xff01; 下面这个场景&#xff1a; 某天线上的项目出bug了&#xff0c;日志打印…

Keil软件仿真的方法: μVision2调试器

目录 1. μVision2调试器2. 调试工具3. 单步调试4. 使用断点调试5. 使用监视窗口调试6. 调试按钮的功能1&#xff0e;“单步”按钮2&#xff0e;“跟踪”按钮3&#xff0e;“运行到退出”按钮4&#xff0e;“运行到光标行”按钮 参考资料 软件仿真是利用PC的CPU来模拟单片机的运…

鸿蒙API9手机号验证

鸿蒙API9手机号验证 做一个app用户认证&#xff0c;之前一直想着都是通过HMS Core里边来接入&#xff0c;但是里边的文档最高只支持到API7。 由于想直接用API9来接&#xff0c;毕竟感觉后续ts/java混合开发要被舍弃&#xff0c;尽量还是用新的来弄。看了一遍新的API9的文档&am…

The-MIFARE-Hack-1 -mifare技术

RFID卡的使用变得越来越普遍。 一般来说&#xff0c;使用两种类型的RFID卡&#xff1a;有源卡和无源卡。 主动系统有自己的能源&#xff0c;而被动系统则依赖读卡器提供的能量。 最常见的 RFID 卡之一是 MIFARE Classic&#xff0c;由 NXP Semiconductors&#xff08;以前是 Ph…

如何强化九小场所安全检查隐患排查工作

九小场所与人们的日常生活息息相关&#xff0c;相关部门对这些场所的消防安全非常重视&#xff1b;但是由于各种原因&#xff0c;经营者安全意识薄弱&#xff0c;导致存在严重的安全隐患。凡尔码开发的九小场所巡检系统针对九小场所基数大、底数不清、责任不明、主体意识薄弱等…

Python大数据之Python进阶(六)多线程的使用

文章目录 多线程的使用1. 导入线程模块2. 线程类Thread参数说明3. 启动线程4. 多线程完成多任务的代码5. 小结 线程执行带有参数的任务1. 线程执行带有参数的任务的介绍2. args参数的使用3. kwargs参数的使用4. 小结 线程的注意点1. 线程的注意点介绍2. 线程之间执行是无序的3.…

5.编写程序 超强力方法

5.1 创建战舰游戏 创建一个类似战舰的游戏&#xff1a;攻击网站 有一种棋盘类的战舰游戏&#xff0c;目标是要猜测对方战舰的坐标&#xff0c;然后轮流开炮攻击&#xff0c;命中数发就可以打沉对方的战舰。不过我们不喜欢战争&#xff0c;只要打垮这些达康公司就好(因为与商业…