【JVM】jvm的双亲委派机制

news2025/1/15 12:58:10

双亲委派机制

  • 一、JVM体系结构
  • 二、双亲委派机制的含义
  • 三、双亲委派机制的源代码
  • 四、双亲委派机制的意义
  • 五、示例代码

一、JVM体系结构

在这里插入图片描述我们先在这里放一张 JVM 的体系架构图,方便我们有个总体认知。

在了解JVM的双亲委派机制之前,你不得不需要知道的几个名字:本文我们只讲上图中里的类加载子系统下的三个阶段之一(Loading,加载阶段)有关的内容,即下图中用红色线圈起来的几个名词。
在这里插入图片描述引导类加载器(Bootstrap ClassLoader);
扩展类加载器(Extension ClassLoader);
应用类加载器(Application ClassLoader)。

有关其详细概念请移步至:【JVM】java的jvm类加载器和类加载子系统之JVM类加载器和类加载子系统里的加载阶段,在这里就不多说了。

二、双亲委派机制的含义

当一个类加载器收到了类加载的请求的时候,它不会直接去加载指定的类,而是把这个请求委托给自己的父加载器去加载。只有父加载器无法加载这个类的时候,才会由当前这个加载器来负责类的加载。

Java中提供如下四种类型的加载器,每一种加载器都有指定的加载对象,具体如下:

  • Bootstrap ClassLoader(引导类加载器) :主要负责加载Java核心类库,%JAVA_HOME%/jre/lib/目录下,resources.jar或者sun.boot.class.path路径下的内容等。
  • Extention ClassLoader(扩展类加载器):主要负责从 java.ext.dirs 系统属性所指定的目录中加载类库,或从JDK的安装目录的**/jre/lib/ext/**子目录(扩展目录)下加载的类库。
  • Application ClassLoader(应用程序类加载器) :主要负责加载当前应用的classpath下的所有类。
  • User-Defined ClassLoader(用户自定义类加载器) : 用户自定义的类加载器,可加载指定路径的class文件。

注意:这里存在的加载器之间的层级关系并不是以继承的方式存在的,而是以组合的方式处理的。

这四种类加载器存在如下关系,当进行类加载的时候,虽然用户自定义类不会由 Bootstrap ClassLoader 或是 Extension ClassLoader 加载(由类加载器的加载范围决定),但是代码实现还是会一直委托到 Bootstrap ClassLoader, 上层无法加载,再由下层是否可以加载,如果都无法加载,就会触发 findclass(),抛出 classNotFoundException

三、双亲委派机制的源代码

打开IDEA等代码开发工具,搜索 ClassLoader 并进入类中,找到 loadClass() 方法,源代码如下:

    /**
     * Loads the class with the specified binary name. 
     * This method searches for classes in the same manner as the loadClass(String, boolean) method.  
     * It is invoked by the Java virtual machine to resolve class references.  
     * Invoking this method is equivalent to invoking #loadClass(String, boolean) loadClass(name,false).
     *
     * @param:  name The binary name of the class
     * @return:  The resulting Class object
     * @throws:  ClassNotFoundException If the class was not found
     */
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }

    /**
     * Loads the class with the specified binary name.  
     * The default implementation of this method searches for classes in the following order:
     *
     * 		1. Invoke #findLoadedClass(String) to check if the class
     *   has already been loaded. 
     *   	2. Invoke the #loadClass(String) loadClass method
     *   on the parent class loader.  If the parent is null the class
     *   loader built-in to the virtual machine is used, instead.  
     *   	3. Invoke the #findClass(String) method to find the
     *   class. 
     * 
     * If the class was found using the above steps, and the
     * resolve flag is true, this method will then invoke the #resolveClass(Class) method on the resulting Class object.
     *
     * Subclasses of ClassLoader are encouraged to override 
     * #findClass(String), rather than this method. 
     *
     * Unless overridden, this method synchronizes on the result of
     * #getClassLoadingLock getClassLoadingLock method
     * during the entire class loading process.
     *
     * @param: name The binary name of the class
     * @param: resolve If true then resolve the class
     * @return: The resulting Class object
     * @throws: ClassNotFoundException If the class could not be found
     */
    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;
        }
    }

其实这段代码已经很好的解释了双亲委派机制,为了大家更容易理解,我做了一张图来描述一下上面这段代码的流程:
在这里插入图片描述从上图中我们就更容易理解了,当一个 Hello.class 这样的文件要被加载时。不考虑我们自定义类加载器,首先会在 AppClassLoader 中检查是否加载过,如果有那就无需再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的 loadClass() 方法。父类中同理也会先检查自己是否已经加载过,如果没有再往上。注意这个类似递归的过程,直到到达 Bootstrap ClassLoader 之前,都是在检查是否加载过,并不会选择自己去加载。直到 Bootstrap ClassLoader,已经没有父加载器了,这时候开始考虑自己是否能加载了,如果自己无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出 ClassNotFoundException。那么有人就有下面这种疑问了?

为什么为有这样的设计?下面我们再来说下这样设计的意义就明白了这样做的好处了。

四、双亲委派机制的意义

这种设计有个好处是:

  • 第一:避免类的重复加载。
  • 第二:保护程序的安全,防止核心API被随意篡改。

如果有人想替换系统级别的类,比如:String.java。篡改它的实现,在这种机制下这些系统的类已经被Bootstrap ClassLoader 加载过了(因为当一个类需要加载的时候,最先去尝试加载的就是 Bootstrap ClassLoader),所以其他类加载器并没有机会再去加载,从一定程度上防止了危险代码的植入。

  1. 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行;
  2. 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器;
  3. 如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。
  4. 父类加载器一层一层往下分配任务,如果子类加载器能加载,则加载此类,如果将加载任务分配至系统类加载器也无法加载此类,则抛出异常。

五、示例代码

现在有一个例子,在我们自定义的 String 类中(包名是 java.lang包下创建),写一个main方法,执行它,如下:

package java.lang;

public class String {

    static {
        System.out.println("这是自定义的String类!");
    }

    public static void main(String[] args) {
        String customClass = new String();
        System.out.println(customClass);
    }
}

执行后的结果如下:
在这里插入图片描述可以看到,报错在java.lang.String中找不到类方法。因为String类是启动类加载器创建的,不是我们自定义的String类,故没有main方法。

完结!

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

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

相关文章

【Mapbox GL JS 入门】Hello world

目录Mapbox GL JS 简介安装Access tokenHello worldMapbox GL JS 简介 官网&#xff1a;https://www.mapbox.com/ git&#xff1a;https://github.com/mapbox/mapbox-gl-js/ 是一个客户端JavaScript库&#xff0c;为了web开发人员可以在web浏览器中动态绘制地图&#xff0c;在…

pico3pro使用unity播放360全景视频及事件交互

1.准备好全景视频&#xff0c;看起来是这样子的。 2.新建一个Materal 注意选择Shader如上图&#xff0c;Render Queue选择AlphaTest&#xff0c;因为我们要在视频前面放置按钮&#xff0c;UI的渲染值为3000&#xff0c;所以可以避免UI不显示的问题&#xff0c;这样UI会一直显示…

代码随想录算法训练营第四十一天| LeetCode343. 整数拆分、LeetCode96. 不同的二叉搜索树

一、LeetCode343. 整数拆分 1&#xff1a;题目描述&#xff08;343. 整数拆分&#xff09; 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 2&#xff1a;…

【Linux系统】网络配置保姆级教学

目录 文章目录网络配置yum install tree 安装和tree显示Linux网络配置[原理图](https://so.csdn.net/so/search?q原理图&spm1001.2101.3001.7020)查看ip和网关ipconfig查看windows网络配置ifconfig查看Linux网络配置ping测试主机之间网络连通性Linux网络环境配置**第一种方…

在 Azure AKS 上部署 EMQX MQTT 服务器集群

云进入以「应用为中心」的云原生阶段&#xff0c;Operator 模式的出现&#xff0c;为 Kubernetes 中的自动化任务创建配置与管理提供了一套行之有效的标准规范。针对大规模分布式物联网 MQTT 消息服务器 EMQX 全生命期管理的自动化管理工具 EMQX Kubernetes Operator&#xff0…

Android最全的setContentView源码分析

前言 我们在开发过程中&#xff0c;在布局文件里添加TextView,代码运行起来就可以看到对应文字显示出来&#xff0c;那系统是如何把我们的TextView加载并显示出来的呢&#xff1f; 源码分析&#xff08;这里版本对应30&#xff09; 第一阶段 我们直接从Activity.setContent…

《第一行代码》核心知识点:Activity(活动)

Android四大组件之一&#xff1a;Activity前言二、Android四大组件之一&#xff1a;Activity(活动)2.1 活动基本介绍2.2 活动的基本用法2.2.1 如何在应用中弹出提示信息2.2.2 如何在活动中添加Menu菜单&#xff08;就一般右上角的三点&#xff09;2.2.3 如何实现活动跳转2.2.5 …

CANoe-什么是Vector Tool Platform(全网唯一讲明白的文章)

在CANoe软件:Home -> Measurement下,有一个功能项,Vector Tool Platform,是做什么用的呢? 点击后打开这个功能页面,发现界面内容不多,包含:设备选择、组件更新、系统更新、远程连接,还有一个连接状态显示 从界面功能猜测:这是一个设备管理和连接的平台。那么是什么…

购买窗帘时哪些可以不做?-江南爱窗帘十大品牌

在家居软装上&#xff0c;窗帘的选择很重要&#xff0c;因为它的存在感很强&#xff0c;占据了墙面的半壁江山。选对了&#xff0c;满心欢喜&#xff0c;选错了&#xff0c;就只能悔恨痛苦了。 1.不做拼色、花纹&#xff1a;拼色窗帘在酒店十分常见&#xff0c;但是不建议照搬回…

14 C++11线程同步之条件变量

在学习条件变量之前需要先了解下std::unique_lock;条件变量 condition_variable需要配合std::unique_lock使用&#xff1b; std::unique_lock std::unique_lock的详细细节参考此篇文章。 C11条件变量 条件变量是 C11 提供的另外一种用于等待的同步机制&#xff0c;它能阻塞…

第04章_运算符

第04章_运算符 1. 算术运算符 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达式&#xff0c;对数值或表达式进行加&#xff08;&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xff08;/&#xff09;和取模&…

使用dbeaver连接GaussDB数据库(集中式)

服务端方式登录 默认初始用户登录方式&#xff1a; [ommgaussdb01 ~]$ gsql -d postgres -p 30100 gsql ((GaussDB Kernel V500R002C10 build 04860477) compiled at 2022-10-28 20:04:35 commit 3892 last mr 8894 release) Non-SSL connection (SSL connection is recommen…

XAML标记扩展(3)

一、RelativeSource属性 我们进行Bingding时&#xff0c;如果明确知道数据源的Name&#xff0c;就能用Source或者ElementName进行绑定&#xff0c;但是有时候我们需要绑定的数据源可能没有明确的Name&#xff0c;此时我们就需要利 用Bingding的RelativeSource进行绑定&#xf…

虚拟数字人/直播/捏脸/3D/metahuman 实时人脸动作捕捉 开发笔记

拍照生成数字人 流程 手机&#xff08;iphone xr以上&#xff09;拍照&#xff08;脸部&#xff09;&#xff0c;导入到unrealmetahuman做数字人 【中文】从0开始捏一个自己的虚拟人&#xff0c;手机扫描到MetaHuman做一个自己的虚拟人_哔哩哔哩_bilibili 涉及APP iphone …

[附源码]java毕业设计校园兼职招聘系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

YUV图像基础知识

概念 YUV和RGB的功能类似&#xff0c;都是用来表示图像色彩的。但是对于 YUV 所表示的图像&#xff0c;Y 和 UV 分量是分离的。如果只有 Y 分量而没有 UV 分离&#xff0c;那么图像表示的就是黑白图像。彩色电视机采用的就是 YUV 图像&#xff0c;解决与和黑白电视机的兼容问题…

swift枚举(二)

swift枚举(一) No-payload enums 布局比较简单&#xff0c;也好理解&#xff0c;接下来看看 Single-payload enums Single-payload enums enum IFLEnum {case test_one(Bool)case test_twocase test_threecase test_four}print(MemoryLayout<IFLEnum>.size)print(Memor…

Vue事件处理器:事件绑定基础、事件修饰符:stop、prevent、capture、self、once;

先看代码&#xff1a; <body><div id"box">{{count}}<button click"handleAdd1()">add1</button><button click"handleAdd2">add2</button></div><script>new Vue({el: "#box",dat…

关于电脑使用的实用技巧

电脑几乎是我们每天都会用到的工具&#xff0c;那么电脑的使用技巧你知道多少呢&#xff1f;今天&#xff0c;我来为大家整理了几个常用的技巧&#xff0c;希望对大家的工作或学习效率有所帮助。 技巧一&#xff1a;快速查找文档按Windows E键打开电脑中的资源管理器&#xff0…

[附源码]SSM计算机毕业设计个性化新闻推荐系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…