【面试题精讲】JVM-双亲委派机制

简介: 【面试题精讲】JVM-双亲委派机制

使用 Arthas 查看加载器继承结构

1. 什么是双亲委派模型?

Java 虚拟机中,类加载器采用双亲委派模型。这个模型是指在类加载的时候,Java 虚拟机采用的是一种层次化的结构来向已经加载的类进行加载,并且将加载请求向父类委派,直到被加载的类能够被找到或者已经到达最顶层的启动类加载器(Bootstrap ClassLoader)为止。

具体来说,双亲委派模型可以分为以下几层:

  1. 启动类加载器(Bootstrap ClassLoader):负责加载 $JAVA_HOME/lib 目录下的核心 Java 类库,本身是由 C++ 实现的,并不是一个 Java 类,是所有其他加载器的父加载器;
  2. 扩展类加载器(Extension ClassLoader):负责加载 $JAVA_HOME/lib/ext 目录下的扩展类库;
  3. 应用程序类加载器(Application ClassLoader):负责加载应用程序路径(classpath)下或者其所引用的第三方库路径下的类库;
  4. 自定义类加载器(Custom ClassLoader):如果应用程序需要,可以通过继承 java.lang.ClassLoader 类实现自己的类加载器,从而实现一些非常复杂的场景需求。

2. 为什么需要双亲委派模型?

双亲委派模型可以保证 Java 类的加载安全,避免了类的重复加载。通过这个模型,能够在 Java 虚拟机中很好地解决类的版本、依赖等问题,当 Java 类需要被加载时,Java 虚拟机会先将请求委派给父类加载器,如果父类加载器不行,再将请求委派给自己去完成。

同时,双亲委派模型还可以保证 Java 类的完整性,确保所加载类来自可信的源,因为 Java 类加载器需要从上至下进行加载。

3. 双亲委派模型的实现原理

在双亲委派模型被引入之前,Java 类加载是通过单一的类加载器实现的。但是单一的类加载器存在很多问题,比如单一类加载器不知道如何处理依赖关系,容易重复加载等问题。因此,为了解决这些问题,并且提高类的加载安全性和效率,提出了双亲委派模型。

双亲委派模型的实现原理非常简单,当一个类需要被加载时,Java 虚拟机会按照如下的流程逐层向上查找:

  1. 当前类加载器会先判断自己是否已经加载过这个类,如果加载过了,就直接返回这个类;
  2. 如果当前类加载器自己没有加载过这个类,那么会调用父类加载器去加载,每一层父类加载器也会按照相同的流程去逐层向上查找,直到父类加载器中已经包含了这个类为止;
  3. 如果到了最顶层的启动类加载器(Bootstrap ClassLoader)还没有包含这个类,那么就由当前的类加载器去加载这个类。

有了双亲委派模型,Java 类加载已经变得简单有效,并且可以保证类的完整性和安全性,能够解决类的依赖和重复加载等问题。

4. 双亲委派模型的使用示例

下面是在 Java 中使用双亲委派模型的示例代码:

public class MyClassLoader extends ClassLoader {
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        // 判断当前加载的类是否已经被加载。如果已经被加载直接返回,如果没有则自己进行加载
        Class clazz = findLoadedClass(name);
        if (clazz != null) {
            return clazz;
        }
        // 将父类加载器加载的对象转化成MyClassLoader加载对象
        clazz = findClass(name);
        if (clazz != null) {
            return clazz;
        }
        // 如果没有内容且不是自己定义的类,则交由父类加载器进行加载
        return super.loadClass(name);
    }
}

在这段代码中,我们自定义了一个 MyClassLoader 类,继承自 Java 的 ClassLoader 类,重写了其中的 loadClass() 方法。在我们自定义的加载器中,首先会检查当前加载的类是否已经被加载,如果已经被加载就直接返回。如果还没有被加载,就会将父类加载器加载的对象转化成我们自己的加载对象,然后再进行对象的加载。最后,如果没有加载到我们需要的对象且不是我们自己定义的类,那么就将这个类交由父类的加载器去加载。

5. 双亲委派模型的优点

双亲委派模型的优点主要体现在以下几个方面:

  1. 类的加载即将任务委派给父类加载器去完成,避免了重复加载,提高了类的加载效率;
  2. 可以保证 Java 类的安全性和完整性,避免了类的替换和被篡改的可能性;
  3. 解决了依赖关系,避免了不同类加载器之间的类依赖关系所带来的问题。

6. 双亲委派模型的缺点

双亲委派模型的缺点主要有以下几个方面:

  1. 双亲委派模型并不适用于所有的场景,对于一些动态生成的类和第三方框架库,使用双亲委派模型可能会让这些类或者库加载失败;
  2. 双亲委派模型在某些情况下可能会导致类的沙箱隔离失效,从而对系统安全性造成影响;
  3. 双亲委派模型可能会导致一些类的重复加载问题。

7. 双亲委派模型的使用注意事项

使用双亲委派模型时需要注意以下事项:

  1. 需要了解双亲委派模型的实现原理,以便在必要的时候进行调整;
  2. 需要了解如何自定义自己的类加载器,并在必要的时候进行实现;
  3. 对于一些需要动态生成类和第三方框架库,需要了解如何避免因为双亲委派模型导致的加载失败问题。

8. 总结

双亲委派模型是 Java 虚拟机中的一种类加载机制,可以保证 Java 类的安全性、完整性和高效性。通过双亲委派模型,Java 类加载机制可以避免重复加载类、解决类之间的依赖关系问题,提高了类的加载效率。双亲委派模型对类的加载做了很好的封装和管理,是 Java 体系机制中的一个非常优秀的设计。但是,对于一些动态生成类和第三方框架库,使用双亲委派模型可能会遇到一些问题,需要在必要的时候进行特殊处理。

本文由 mdnice 多平台发布


相关文章
|
3月前
|
安全 前端开发 Java
【JVM的秘密揭秘】深入理解类加载器与双亲委派机制的奥秘!
【8月更文挑战第25天】在Java技术栈中,深入理解JVM类加载机制及其双亲委派模型是至关重要的。JVM类加载器作为运行时系统的关键组件,负责将字节码文件加载至内存并转换为可执行的数据结构。其采用层级结构,包括引导、扩展、应用及用户自定义类加载器,通过双亲委派机制协同工作,确保Java核心库的安全性与稳定性。本文通过解析类加载器的分类、双亲委派机制原理及示例代码,帮助读者全面掌握这一核心概念,为开发更安全高效的Java应用程序奠定基础。
87 0
|
24天前
|
存储 监控 算法
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程 ?
尼恩提示: G1垃圾回收 原理非常重要, 是面试的重点, 大家一定要好好掌握
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程  ?
|
15天前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
|
19天前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
41 1
|
21天前
|
监控 架构师 Java
从蚂蚁金服面试题窥探STW机制
在Java虚拟机(JVM)中,垃圾回收(GC)是一个至关重要的机制,它负责自动管理内存的分配和释放。然而,垃圾回收过程并非没有代价,其中最为显著的一个影响就是STW(Stop-The-World)机制。STW机制是指在垃圾回收过程中,JVM会暂停所有应用线程的执行,以确保垃圾回收器能够正确地遍历和回收对象。这一机制虽然保证了垃圾回收的安全性和准确性,但也可能对应用程序的性能产生显著影响。
19 2
|
23天前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
26天前
|
缓存 前端开发 Java
JVM知识体系学习二:ClassLoader 类加载器、类加载器层次、类过载过程之双亲委派机制、类加载范围、自定义类加载器、编译器、懒加载模式、打破双亲委派机制
这篇文章详细介绍了JVM中ClassLoader的工作原理,包括类加载器的层次结构、双亲委派机制、类加载过程、自定义类加载器的实现,以及如何打破双亲委派机制来实现热部署等功能。
37 3
|
2月前
|
存储 缓存 监控
【Java面试题汇总】JVM篇(2023版)
JVM内存模型、双亲委派模型、类加载机制、内存溢出、垃圾回收机制、内存泄漏、垃圾回收流程、垃圾回收器、G1、CMS、JVM调优
【Java面试题汇总】JVM篇(2023版)
|
24天前
|
存储 Kubernetes 架构师
阿里面试:JVM 锁内存 是怎么变化的? JVM 锁的膨胀过程 ?
尼恩,一位经验丰富的40岁老架构师,通过其读者交流群分享了一系列关于JVM锁的深度解析,包括偏向锁、轻量级锁、自旋锁和重量级锁的概念、内存结构变化及锁膨胀流程。这些内容不仅帮助群内的小伙伴们顺利通过了多家一线互联网企业的面试,还整理成了《尼恩Java面试宝典》等技术资料,助力更多开发者提升技术水平,实现职业逆袭。尼恩强调,掌握这些核心知识点不仅能提高面试成功率,还能在实际工作中更好地应对高并发场景下的性能优化问题。