深入理解java虚拟机系列第三版读后小记:(十一)jvm的类加载器

前言

本文将介绍一下java的类加载器,了解它的功能以及和类的关系。

类与类加载器

之前提到类被加载到jvm中的第一个阶段就是加载,而加载类的就是其类加载器,所以类与其类加载器共同确立了jvm中的唯一性,也就是说通常判断两个对象是否相等是的前提是由同一个类加载器加载的,如果两个对象外形一样但是由不同的类加载器加载,那两对象肯定不相等。

双亲委派模型

介绍双亲委派之前,先谈谈类加载器的种类,从jvm角度来看,只有两种类加载器:

  • 启动类加载器(Bootstrap classLoader)这是由c++实现,是虚拟机自身的一部分。
  • 其他类加载器,这些全都由java实现,独立存在虚拟机外部,并全部继承抽象类为java…lang.ClassLoader

站在java开发人员的角度,类加载结构就更加细致,划分为三层类加载器。

  • 启动类加载器,负责加载java_home/lib 下的目录
  • 扩展类加载器 (Extension Class Loader),负责加载java_home/lib/ext 目录下,由java实现。

·应用程序类加载器(Application Class Loader),又成为系统类加载器,负责加载用户类路径上的所有类库,如果程序中没有自定义的类加载器,这就是默认的类加载器。

在这里插入图片描述
如图,双亲委派模型。

概念

图上所显示的各种类加载器之间的层次关系就称为双亲委派模型,双亲委派模型要求除了顶层的启动类加载器外,其余类加载器都应有自己的父加载器,这里描述的父子关系通常不是以继承实现的,而是以组合个关系复用父加载器的代码。

工作流程

双亲委派的工作流程简单易懂,如果一个类加载器收到一个类的加载请求,就将其委派给父加载器加载,妹个层次的类加载器都是如此,所以最终所有的类都会委派到顶层类加载器启动类加载器去加载,只有当父加载器反馈自己无法加载此类(它的搜索范围没有找到所需的类)时,才会让子类加载器尝试加载。

优点

了解到它的工作机制,双亲委派的优点也显而易见,就是类随着其类加载器具有了优先级的层次概念,如rt.jar内的java.lang.Object类,任何路径的类加载器加载它最终都会由启动类加载器去加载,如果没有双清委派,由各个类加载器自行加载,那系统中就会许多不同个java.lang.Obeject对象,整个系统就会混乱了。所以,双亲委派对保护程序的稳定性极其重要,越基础越重要的类就越先交给统一的父加载器进行加载。

双亲委派的破坏

因为双亲委派并不是一个强制性的约束模型,只是java设计者推荐费开发者类加载实现方式,所以是可以被破坏的。

第一次破坏

未出现双清委派模型之前,双亲委派是jdk1.2才出现的,所以1.2 出来后为了向下兼容不得做出妥协,兼容jdk1.2之前的类加载所以进行了模型的破坏,提供了一个保护方法给用户实现,即父加载器加载失败的时候,由用户覆写的方法去实现类加载过程。

第二次破坏

自身缺陷,双亲委派的思想就是越基础的类越由上层类加载器加载,一些特殊场景,如基础类回调用户的代码,JNDI的场景下,双亲委派就无法完美的实现。采取的解决方案就是线程的上下文加载器,这个类加载器可以通过java.lang.Thread类的setContext-ClassLoader()方法进行设置,如果创建线程时还未设置,就会从父线程继承,所以开发者可以指定调用下层的类加载器。

第三次破坏

用户程序的动态性导致,代码热替换,模块热部署等,简单来说就是希望java程序像电脑的外设一样,支持热插拔,不需重启系统,所以基于这种思想,双亲委派模型不再适用,而是变为更复杂的网式模型。
其加载过程也变了:

  • java.*开头的类委派给父加载器
  • 否则,委派名单内的类委派给父加载器
  • 否则,import列表中的类,委派Export这个类的模块(Bundle)内类加载器加载
  • 否则,使用自己模块的类加载器
  • 否则,查找类是否在自己的Fragment Bundle中,如果在,则委派给Fragment Bundle的类加载器
    加载。
  • 否则,查找Dynamic Import列表的Bundle,委派给对应Bundle的类加载器加载。
  • 否则,类查找失败。

模块思想

其模块是在jdk9之后才出现的,其思想和上文提的一样,希望java 能够热部署一样。所以jdk 9之后的类加载模型不再是单纯的双亲委派
在这里插入图片描述
当应用程序和平台类加载器收到类加载请求,不再是单独的委托给父加载,再其之前会检查能否归属到一个模块中的话,就先加载模块中的类加载器进行加载。

总结

本文详细的介绍了类加载器和双亲委派的模型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值