【深入Java虚拟机】二 类加载与双亲委派
https://blog.csdn.net/zhangliangzi/article/details/51338291 -参考
双亲委派过程:当一个类加载器收到类加载任务时,立即将任务委派给它的父类加载器去执行,直至委派给最顶层的启动类加载器为止。如果父类加载器无法加载委派给它的类时,将类加载任务退回给它的下一级加载器去执行;除了启动类加载器以外,每个类加载器拥有一个父类加载器,用户的自定义类加载器的父类加载器是AppClassLoader;双亲委派模型可以保证全限名指定的类,只被加载一次;双亲委派模型不具有强制性约束,是Java设计者推荐的类加载器实现方式;
双亲委派模型的源码实现:
主要体现在ClassLoader的loadClass()方法中,思路很简单:先检查是否已经被加载过,若没有加载则调用父类加载器的loadClass()方法,若父类加载器为空则默认使用启动类加载器作为父类加载器。如果父类加载器加载失败,抛出ClassNotFoundException异常后,调用自己的findClass()方法进行加载。
/**
* Loads the class with the specified <a href="#name">binary name</a>. The
* default implementation of this method searches for classes in the
* following order:
*
* <ol>
*
* <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
* has already been loaded. </p></li>
*
* <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
* on the parent class loader. If the parent is <tt>null</tt> the class
* loader built-in to the virtual machine is used, instead. </p></li>
*
* <li><p> Invoke the {@link #findClass(String)} method to find the
* class. </p></li>
*
* </ol>
*
* <p> If the class was found using the above steps, and the
* <tt>resolve</tt> flag is true, this method will then invoke the {@link
* #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
*
* <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
* #findClass(String)}, rather than this method. </p>
*
* <p> Unless overridden, this method synchronizes on the result of
* {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
* during the entire class loading process.
*
* @param name
* The <a href="#name">binary name</a> of the class
*
* @param resolve
* If <tt>true</tt> then resolve the class
*
* @return The resulting <tt>Class</tt> object
*
* @throws ClassNotFoundException
* If the class could not be found
*/
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} 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;
}
}
双亲委派的好处:
使用双亲委派模型来组织类加载器之间的关系,有一个很明显的好处,就是Java类随着它的类加载器(说白了,就是它所在的目录)一起具备了一种带有优先级的层次关系,这对于保证Java程序的稳定运作很重要。例如,类java.lang.Object类存放在JDK\jre\lib下的rt.jar之中,因此无论是哪个类加载器要加载此类,最终都会委派给启动类加载器进行加载,这边保证了Object类在程序中的各种类加载器中都是同一个类。
破坏双亲委派的模型:
参考:
[1] 《Java虚拟机精讲》[2] 《深入理解Java虚拟机 JVM高级特性与最佳实践》[3] http://blog.csdn.net/zhangliangzi/article/details/51338291
[2] tomcat类加载器
[3] 深入探讨 Java 类加载器:https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html
[4] 深入理解 Tomcat(四)Tomcat 类加载器之为何违背双亲委派模型 https://blog.csdn.net/qq_38182963/article/details/78660779
【深入Java虚拟机】二 类加载与双亲委派的更多相关文章
- java虚拟机(二)--类加载机制和双亲委派模型
一.类的生命周期 加载(Loading).验证(Verification).准备(Preparation).解析(Resolution).初始化(Initialization).使用(Using).卸 ...
- java 虚拟机的类加载机制
Java 虚拟机的类加载机制 关于类加载机制: 虚拟机把描述类的数据从Class 文件加载到内存,并对数据进行效验.转换解析和初始化,最终 形成可以被虚拟机直接使用的Java 类型,就是虚拟机的类 ...
- 深入探究JVM之类加载与双亲委派机制
@ 目录 前言 类的生命周期 加载 验证 准备 解析 初始化 案例一 案例二 案例三 案例四 类加载器 类加载器和双亲委派模型 破坏双亲委派模型 第一次 SPI Tomcat OSGI 总结 前言 前 ...
- 深入理解java虚拟机【类加载机制】
Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 在加载阶段,java虚拟机需要完成以下 ...
- JVM类加载与双亲委派机制被打破
前言 前文已经讲了虚拟机将java文件编译成class文件后的格式:JVM虚拟机Class类文件研究分析 java文件经过编译,形成class文件,那么虚拟机如何将这些Class文件读取到内存中呢? ...
- [五]类加载机制双亲委派机制 底层代码实现原理 源码分析 java类加载双亲委派机制是如何实现的
Launcher启动类 本文是双亲委派机制的源码分析部分,类加载机制中的双亲委派模型对于jvm的稳定运行是非常重要的 不过源码其实比较简单,接下来简单介绍一下 我们先从启动类说起 有一个Lau ...
- JVM学习六:JVM之类加载器之双亲委派机制
前面我们知道类加载有系统自带的3种加载器,也有自定义的加载器,那么这些加载器之间的关系是什么,已经在加载类的时候,谁去加载呢?这节,我们将进行讲解. 一.双亲委派机制 JVM的ClassLoader采 ...
- 深入理解Java虚拟机(类加载机制)
文章首发于微信公众号:BaronTalk 上一篇文章我们介绍了「类文件结构」,这一篇我们来看看虚拟机是如何加载类的. 我们的源代码经过编译器编译成字节码之后,最终都需要加载到虚拟机之后才能运行.虚拟机 ...
- 【java虚拟机】类加载机制
作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/6959615.html 一.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中, ...
随机推荐
- BZOJ2240 : ural1676 Mortal Combat
首先如果最大匹配不足$n$个那么显然每条边都不可能在匹配为$n$的方案中. 对于一条边$(u,v)$,如果它可能在最大匹配中,有两种情况: $1.(u,v)$是当前方案的匹配边. $2.$可以沿着$( ...
- JS 函数表达式
定义函数的方式有两种, 一种是函数声明,一种就是函数表达式了 函数声明最常见了, sayHi(); // 函数声明会发生提升 function sayHi () { alert('Hi') } 函数表 ...
- js写滚动的文字
页面中的文字,逐个显示在页面:由于电脑的配置较低,录制的视频相对来说比较卡顿 思路: 用一个定时器将预制的文字通过字符串截取.substring(0, i)方法不断的赋给要显示的区域,i在定时器里面迭 ...
- Html表单标签:
表单用于收集不同的类型的用户输入,表单由不同类型的标签组成,相关标签及属性如下: (1)<form>标签 定义整体的表单区域 -- action属性 定义表单数据提交址址 -- metho ...
- Node_初步了解(2)
1. windown下 npm 升级: npm install npm -g 2. Node.js事件驱动模型:设计模型——观察者模型. 3. node.js全局变量:global 4. node.j ...
- js,css文件更新之后,浏览器端还有缓存,久久不能消除
解决方案,每次更新之后修改下配置信息 /// <summary> /// VersionInfo 版本信息 /// </summary> public static class ...
- Gird Layout代码解释
<div class="wrapper"> <!--定义一个类名为wrapper的div盒子--> <div class="one" ...
- Js实现Table动态添加一行的小例子
<form id="form1" runat="server"> <div> <table id=" style=&qu ...
- 如何做好Puppet Modules管理
如何做好Puppet Modules管理 不同于其他的Openstack项目,puppet modules是一个数量庞大的存在.以我们当前在使用中的puppet modules为例,就已经多达96个( ...
- sort is deprecated, use sort_values(inplace=True) for INPLACE sorting
排序是过时的,用sort_values(到位=真)为就地排序