博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java类加载机制
阅读量:4916 次
发布时间:2019-06-11

本文共 2984 字,大约阅读时间需要 9 分钟。

1. 双亲委派模型

JVM内置了三个ClassLoader

  • Bootstrap ClassLoader:负责加载%JAVA_HOME%/lib目录中的class(比方说rt.jar里的class),这个ClassLoader是JVM底层实现的,我们无法直接操作
  • Extension ClassLoader:负责加载%JAVA_HOME%/lib/ext中的所有类库(比方说jfxrt.jar,这个大概是JavaFX的核心库?),这个ClassLoader的实现位于sun.misc.Launcher$ExtClassLoader,我们可以直接使用
  • System ClassLoader:负责加载%CLASSPATH%路径的类库,也就是一般的Java程序本体,以及它所依赖的第三方jar包了。这个ClassLoader的实现位于sun.misc.Launcher$AppClassLoader,我们可以直接使用

上面的ClassLoader是下面的ClassLoader的祖先。(其实调用ExtClassLoader的getParent方法会返回null,但是依然可以认为Bootstrap ClassLoader是Extension ClassLoader的祖先)

所谓的双亲委派模型(parent-delegation-model),是指某个ClassLoader在收到loadClass的请求时,先将这个请求转发给父ClassLoader,如果父ClassLoader无法加载此Class,再有当前ClassLoader进行加载。

请注意,这个加载操作是递归的,也就是说每个loadClass的请求都会经过System ClassLoader -> Extension ClassLoader -> Bootstrap ClassLoader这样的流程。

ps,其实我觉得这个命名不太好,为啥要叫parent-delegation-model呢,我以前一直以为一个ClassLoader有两个父ClassLoader来着。不如叫ancestor-delegation-model,然后翻译为祖先委派模型比较妥当?

 

2. 双亲委派模型的意义

概括的说:防止同一个Class被加载多次

如果我们想要加载最基本的java.lang.Object,在双亲委派模型下,不管使用哪个ClassLoader,最终都会追溯到Bootstrap ClassLoader进行加载

这样就保证了整个JVM中,有且只有一个java.lang.Object

如果不遵守双亲委派模型, 就有可能出现一个JVM内含有多个不同的ClassLoader加载的java.lang.Object的情况,这会引起混乱。

 

3. 双亲委派模型的实现

参考JDK1.8.0_66的java.lang.ClassLoader的loadClass方法的源码

protected Class
loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) {
//禁止多线程同时load同一个Class // First, check if the class has already been loaded Class
c = findLoadedClass(name);//看cache里是否已经存在这个Class了,会调用一个native方法 if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false);//调用父ClassLoader的loadClass方法,这里就是双亲委派机制的关键了 } else { c = findBootstrapClassOrNull(name);//父ClassLoader为null,那么父ClassLoader肯定是Bootstrap ClasLoader了,调用native方法让Bootstrap ClassLoader来加载这个Class } } 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; } }

 

4. 对双亲委派模型的破坏

双亲委派模型只是一种建议,在某些需要高度灵活性的场景下,我们不必遵守双亲委派模型。

比方说Tomcat

 

 

参考文献

转载于:https://www.cnblogs.com/stevenczp/p/7367737.html

你可能感兴趣的文章
常用vim命令
查看>>
Day18 高阶函数
查看>>
Tomcat工作原理
查看>>
我的Python分析成长之路7
查看>>
Window对象 setInterval()方法应用
查看>>
CSS样式-文字在一行内显示不换行,超出部分用省略号(white-space、overflow、text-overflow、word-wrap、word-break)...
查看>>
Linux下安装jdk
查看>>
python 中关于descriptor的一些知识问题
查看>>
Golang的方法传递值应该注意的地方
查看>>
XMIND 是一款非常实用的商业思维导图(Mindmap)软件
查看>>
Intent 匹配规则
查看>>
windows 安装nvm步骤(shi'yongnvm-windows管理node版本):
查看>>
JdbcUtils
查看>>
「SCOI2014」方伯伯的玉米田 解题报告
查看>>
eclipse中web项目部署到本地tomcat中,但是在本地的tomcat的webapp下找不到发布的项目...
查看>>
使用PHP连接、操纵Memcached的原理和教程
查看>>
在网页中运用统计Web Service接口
查看>>
python入门(八):连接mysql和STMP
查看>>
将图片地址转为blob格式的例子
查看>>
Entity Framework In Action(1)——数据环境准备
查看>>