模拟面试回答第十四问:双亲委派模型

简介(总)

对于双亲委派模型,我从几个方面来介绍,类加载,类加载器,双亲委派模型,好处,打破双亲委派以及JDK8到9模型产生的变化六个方面。

类加载(分1)

首先是类加载,当我们new一个对象实例时或者执行某类的main方法时都会触发类加载,类加载的作用就是为了让JVM认识这个类,知道它的各种信息,比如字段,方法,继承了哪些类,方法内引用了哪些对象,实例需要分配多大内存等等,类加载有五个阶段,加载、验证、准备、解析、初始化。不过本题我们关注的不是加载过程中,而是加载之前,这个类加载请求是由谁呈递的,那答案是类加载器。

类加载器(分2)

JVM设计了三层类加载器负责加载不同的类,每层类加载器都有自己负责的范围,分别是启动类加载器,扩展类加载器,应用类加载器。启动类加载器是最顶层的,负责加载JAVA_HOME/lib目录中的Jar包;扩展类加载器负责加载JAVA_HOME/lib/ext目录中的Jar包;应用类加载器负责加载当前项目路径下的类和引入的三方依赖。

双亲委派模型(分3)

那双亲委派模型就是指这些类加载器的加载优先级,子类加载器收到类请求后,优先委派给父类加载器,如果父类加载器无法加载,自己再加载,这就是双亲委派模型。

好处 (分4)

双亲委派模型有两点主要好处:

  1. 保证核心类库的安全,比如我自己写了一个java.lang.String.class放在项目路径下,属于应用类加载器负责的范围,当触发String的类加载时,应用类加载器接受到请求后不会自己加载,而是优先交给扩展类加载器,扩展类再交给启动类加载器,启动类加载器检索类库,找到了核心类java.lang.String.class,执行类加载。这证明了核心类不会被自己写的同名类替代,保证安全。
  2. 避免重复加载,当启动类加载器加载了String类之后,扩展类和应用类加载器就不会再加载了,加载请求结束了。

打破(分5)

有没有特殊场景需要打破双亲委派模型呢?有的,兄弟,有的,那就是Tomcat,这是一个Web服务器,Tomcat运行多个应用,不同应用可能使用不同的依赖版本,这是Tomcat的需求。而双亲委派模型会使这些应用加载同一个版本,所以Tomcat自己实现了WebAppClassLoader类,重写了loadClass()方法,重写逻辑变成先自己加载,找不到再委派给父类。Tomcat运行应用时为每个应用创建WebAppClassLoader实例,实现了应用隔离。

这样做的好处除了隔离性之外,还有热部署和安全性。重新部署应用时将之前WebAppClassLoader删掉,重新创建一个,不会被缓存干扰;不同的应用不能访问各自的类,因为加载器实例不同。

迭代变化(分6)

JDK8是个分水岭,类加载器和双亲委派模型都有变化,类加载器将扩展类加载器变成了平台类加载器,并且加载器的加载模式变了,不再是以前的匹配路径加载Jar包,而是加载模块,启动类加载器加载java.base等核心模块,平台累加载器加载java.sal,java.xml等非核心但常用的模块,应用类加载器加载项目中自己写的类和三方依赖,三方依赖可能是模块,也可能是原始Jar包。那模块到底是什么呢?其实就是加入了一些额外信息的Jar包,主要包括依赖信息。

这个依赖信息导致双亲委派模型也有变化,委派逻辑不再是严格的向上委派,而是根据模块间的依赖关系进行委派,比如java.xml模块依赖应用类加载器负责的A模块,那加载java.xml模块的类之前先要委托应用类加载器加载A模块,之后再加载java.xml的类。

这样做的好处就是更加灵活。

相关推荐
u01091476021 小时前
CSS组件库如何快速扩展_通过Sass @extend继承基础布局
jvm·数据库·python
爱敲键盘的猴子21 小时前
JVM -- 内存模型(运行时数据区,垃圾回收机制)
jvm
baidu_3409988221 小时前
Golang怎么用go-noescape优化性能_Golang如何使用编译器指令控制逃逸分析行为【进阶】
jvm·数据库·python
m0_6784854521 小时前
如何利用虚拟 DOM 实现无痕刷新?基于 VNode 对比的状态保持技巧
jvm·数据库·python
qq_3422958221 小时前
CSS如何实现透明背景效果_通过RGBA色彩模式控制透明度
jvm·数据库·python
Greyson11 天前
CSS如何处理超长文本换行问题_结合word-wrap属性
jvm·数据库·python
怕浪猫1 天前
2026 年前端工程师面试:一份来自面试官视角的真实复盘
面试
justjinji1 天前
如何批量更新SQL数据表_使用UPDATE JOIN语法提升效率
jvm·数据库·python
weixin_580614001 天前
MySQL存储过程中如何防止SQL注入_使用参数化查询规范
jvm·数据库·python
2401_837163891 天前
PHP源码开发用台式机还是笔记本更合适_硬件选型对比【方法】
jvm·数据库·python