资讯专栏INFORMATION COLUMN

类加载器以及双亲委派模型

曹金海 / 2339人阅读

摘要:宗主引导类加载器。双亲委派模型是如何使用的我们在自定义加载器中查找是否有需要加载的文件,如果已经加载过,直接返回字节码。

作者:毕来生
微信:878799579
1、小故事理解类加载器以及双亲委派模型

首先我们来描述一个小说场景,通过这个场景在去理解我们相关的类加载器的执行以及双亲委派模型。

上古时代有逍遥派和万魔宗两个宗派,互相对立。逍遥派比万魔门更加强势。巅峰战力更高。

有一天万魔宗一名长老之子的仆人外出猎物期间杀掉了一小队逍遥派历练弟子。可惜手脚不干净,留下了线索。被逍遥派探子发现了自己师弟师妹被杀。消息传回宗门后。

逍遥派收到此消息后大怒,发出战书。定要万魔门给个交代。万魔门宗主收到战书后一脸莫名其妙,这么点小事也来烦我?不知道我修炼有多重要吗?不就是杀了几个人么?遂叫来大长老,“大长老你看看这战书,这么点事情还办不好还要我亲自来处理?要你有什么用 ? 你去准备点东西把这件事情处理一下。退下吧!”

大长老灰溜溜的回去。叫来自己的儿子。上去就抽了一巴掌,看看你办的好事。我不管了。你自己想办法解决,解决不了就别回来了。

大长老之子哭丧着脸回到了自己的府邸。从自己的宝库挑出一些珍宝前去拜访逍遥门,看能不能通过这些珍宝解决这件事情。结果,到了逍遥派门前,守卫一看就这么点东西就想交代。对万魔门大长老之子说:"赶紧滚关进滚,就这么点东西还想给我们交代?把杀了我们师弟师妹的人带过来,不然这事儿不算完。“

大长老之子那叫一个憋屈呀,宝物什么的他们也不要,看样子他们是铁了心想要哪些杀了他们的罪魁祸首。那就把他们交出去把。他们惹的事。让他们自己解决。遂派人抓捕这些人送往逍遥派,此事才得以平息。

2、小故事角色行为分析

下面我们通过一张关系图来分析一下我们的故事场景以及对应我们类加载器之间的关系

通过这个图我们可以了解到我们的小故事中与我们Java中的类加载器的对应关系。

1、宗主:引导类加载器。这个类加载使用C++语言实现的,是虚拟机自身的一部分,它负责将 /lib路径下的核心类库或-Xbootclasspath参数指定的路径下的jar包加载到内存中,注意必由于虚拟机是按照文件名识别加载jar包的,如rt.jar,如果文件名不被虚拟机识别,即使把jar包丢到lib目录下也是没有作用的(出于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类)。

2、长老:拓展类加载器。,它负责加载/lib/ext目录下或者由系统变量-Djava.ext.dir指定位路径中的类库,开发人员可以直接使用标准扩展类加载器。

3、长老之子:系统类加载器。,它负责加载系统类路径java -classpath或-D java.class.path 指定路径下的类库,也就是我们经常用到的classpath路径,开发者可以直接使用系统类加载器,一般情况下该类加载是程序中默认的类加载器,通过ClassLoader类中的getSystemClassLoader()方法可以获取到该类加载器。

4、长老之子的下人:自定义类加载器。,它需要如下步骤才可以实现自定义效果

4.1. 继承java.lang.ClassLoader

4.2. 重写findClass()方法

4.3 调用defineClass()方法

双亲委派模型

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

特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。

2、双亲委派模型是如何使用的?

1)我们在自定义加载器中查找是否有需要加载的文件,如果已经加载过,直接返回字节码。

对应故事场景为:长老之子的下人自己解决不了,找到长老之子

2)如果自定义加载器没有加载过,则询问上一层加载器(即AppClassLoader)是否已经加载过。

对应故事场景为:长老之子携带宝物前去拜访解决此事

3) 如果没有加载过,则询问上一层加载器(ExtClassLoader)是否已经加载过。

对应故事场景为:大长老解决此事

4) 如果没有加载过,则继续询问上一层加载(BoopStrap ClassLoader)是否已经加载过

对应故事场景为:宗主解决此事

5) 如果BoopStrap ClassLoader依然没有加载过,则到自己指定类加载路径下("sun.boot.class.path")

查看是否有对应XXX.class字节码,有则返回,没有则通知下一层加载器ExtClassLoader到自己指定的

类加载路径下(java.ext.dirs)查看

6) 最后到自定义类加载器指定的路径还没有找到对应XXX.class字节码,则抛出异常ClassNotFoundException

双亲委派有什么好处呢?

1、比如两个类A和类B都要加载Integer类:

如果不用委托而是自己加载自己的,那么类A就会加载一份Integer字节码,然后类B又会加载一份Integer字节码,这样内存中就出现了两份Integer字节码。

如果使用委托机制,会递归的向父类查找,也就是首选用Bootstrap尝试加载,如果找不到再向下。这里的Integer就能在Bootstrap中找到然后加载,如果此时类B也要加载Integer,也从Bootstrap开始,此时Bootstrap发现已经加载过了Integer那么直接返回内存中的Integer而不需要重新加载,这样内存中就只有一份Integer的字节码了。

2、 安全性:

因为ClassLoader加载的class文件来源很多,比如编译器编译生成的class、其他工具生成的字节码。而有一些一些来源的class文件是不安全的,比如我们自定义一个java.lang.Integer类来覆盖jdk中默认的Integer类。里面写这么一句代码 System.exit(0);

初始化这个Integer的构造器是会退出JVM,破坏应用程序的正常进行,如果使用双亲委派机制的话该Integer类永远不会被调用,以为委托BootStrapClassLoader加载后会加载JDK中的Integer类而不会加载自定义的这个

喜欢就关注我吧

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75689.html

相关文章

  • Java的加载机制

    摘要:如果需要支持类的动态加载或需要对编译后的字节码文件进行解密操作等,就需要与类加载器打交道了。双亲委派模型,双亲委派模型,约定类加载器的加载机制。任何之类的字节码都无法调用方法,因为该方法只能在类加载的过程中由调用。 jvm系列 垃圾回收基础 JVM的编译策略 GC的三大基础算法 GC的三大高级算法 GC策略的评价指标 JVM信息查看 GC通用日志解读 jvm的card table数据...

    aervon 评论0 收藏0
  • 加载机制,双亲委派模型,搞定大厂高频面试题

    摘要:验证验证是连接阶段的第一步,这一阶段的目的是为了确保文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。字节码验证通过数据流和控制流分析,确定程序语义是合法的符合逻辑的。 看过这篇文章,大厂面试你「双亲委派模型」,硬气的说一句,你怕啥? 读该文章姿势 打开手头的 IDE,按照文章内容及思路进行代码跟踪与思考 手头没有 IDE,先收藏,回头看 (万一哪次面试问...

    Object 评论0 收藏0
  • JVM加载过程 & 双亲委派模型

    摘要:类加载过程双亲委派模型声明文章均为本人技术笔记,转载请注明出处类加载过程类加载机制将类描述数据从文件中加载到内存,并对数据进行,解析和初始化,最终形成被直接使用的类型。深入理解虚拟机高级特性与最佳实践加载加载阶段由类加载器负责,过程见类加载 JVM类加载过程 & 双亲委派模型 声明 文章均为本人技术笔记,转载请注明出处https://segmentfault.com/u/yzwall ...

    happen 评论0 收藏0
  • Java加载机制之双亲委派模型

    摘要:比如我们要加载类,无论我们用哪个类加载器去加载类,这个加载请求最终都会委托给,这样就保证了所有加载器加载的类都是同一个类。如果没有双亲委派模型,那就乱了套了,完全可能搞出多个不同的类。 前言 双亲委派模型是Java加载类的机制.采用双亲委派模型的好处是Java类随着它的类加载器一起具备了一种带有优先级的层级关系,通过这种层级关系可以避免类的重复加载. 1. 模型基础 showImg(h...

    X_AirDu 评论0 收藏0
  • 深入理解虚拟机之虚拟机加载机制

    摘要:最终形成可以被虚拟机最直接使用的类型的过程就是虚拟机的类加载机制。即重写一个类加载器的方法验证验证是连接阶段的第一步,这一阶段的目的是为了确保文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。 《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版》读书笔记与常见相关面试题总结 本节常见面试题(推荐带着问题阅读,问题答案在文中都有提到): 简单说说类加载过...

    MadPecker 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<