JVM(三、双亲委派机制)
javadoc的解释:
ClassLoader的每一个实例都会有一个与之关联的父ClassLoader,当被要求去寻找一个类或者资源的时候,ClassLoader的实例就会对于类或者是资源的寻找委托给他的父ClassLoader(在他自己尝试找这个类或者资源之前),并层层向上委托。
虚拟机内建的ClassLoader即Bootstrap根类加载器,他本身是没有双亲的,但是他可以作为一个类加载器的双亲。
支持并发加载类的类加载器,被称为 parallel capable class loaders ,被要求在类的初始化期间调用ClassLoader.registerAsParallelCapable()将自身注册为parallelcapableclassloader。 ClassLoader默认是并发类加载器,但他的子类如果是并发的,还依然需要注册。
当境委派模型并不是严格的层次委派模型时,要求类加载器必须是支持并行的类加载器,否则类加载就会导致死锁。因为加载器的锁(loader lock我也不知道咋翻译)在类的加载过程中一直不会释放。
一般来说jvm虚拟机加载类来源于本地文件系统(与操作系统跟平台相关),但也可能来源于其他资源,比如网络,或者运行时的动态生成。
在这种情况下,加载类的方法会把一个字节数组(调用 loadClassData() 返回byte[] ,通过defineClass(byte[])转为一个Class)转换为一个class对象,通过Class.newInstance 来创建对应对象。
class NetworkClassLoader extends ClassLoader { public Class findClass(String name) { private byte[] loadClassData(String name) { } |
由类加载器创建的对象,其方法或者构造器可能引用了其他未加载的类,为了确定这些引用是什么(注意这些引用对应的类还未被装入,需要确定这些引用是什么) jvm虚拟机会调用加载这个类的class的classloader 来加载这些引用(再次跳入第一步 开始递归)
1.获取ClassLoader
public class MyTest06 { public static void main(String[] args) {
String str = new String("212");
C c = new C();
System.out.println(str.getClass().getClassLoader());
System.out.println(c.getClass().getClassLoader());
} }
class C{ }//out: null
sun.misc.Launcher$AppClassLoader@2a139a55
第二个返回值说明自定义类C是由AppClassLoader 系统类加载器加载
第一个返回值说明String由Bootstrap根加载器加载
/** 如下是源码中对 getClassLoader() 方法的说明
* Returns the class loader for the class. Some implementations may use
* null to represent the bootstrap class loader. This method will return
* null in such implementations if this class was loaded by the bootstrap
* class loader.
* 如果类由bootstrap class loader加载 这个方法会返回null在一些jvm实现中
*
* <p> If a security manager is present, and the caller's class loader is
* not null and the caller's class loader is not the same as or an ancestor of
* the class loader for the class whose class loader is requested, then
* this method calls the security manager's {@code checkPermission}
* method with a {@code RuntimePermission("getClassLoader")}
* permission to ensure it's ok to access the class loader for the class.
*
* <p>If this object
* represents a primitive type or void, null is returned.
*
* @return the class loader that loaded the class or interface
* represented by this object.
* @throws SecurityException
* if a security manager exists and its
* {@code checkPermission} method denies
* access to the class loader for the class.
* @see java.lang.ClassLoader
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
*/
2.ClassLoader.loadClass()方法与Class.forName()方法
class CL{
static {
System.out.println("class cl");
}
}
public class MyTest07 { public static void main(String[] args) throws Exception {
ClassLoader clazzloader = ClassLoader.getSystemClassLoader();
Class<?> clazz = clazzloader.loadClass("jvm.CL");
System.out.println("==================================");
System.out.println(clazz);
System.out.println("==================================");
Class<?> clazz2 = Class.forName("jvm.CL");
System.out.println("==================================");
System.out.println(clazz2);
} }//out:
==================================
class jvm.CL
==================================
class cl
==================================
class jvm.CL
loadclass 只加载对应类,forName 会一并将类初始化
不过调用 clazz.newInstance()会初始化该类:
public class MyTest07 { public static void main(String[] args) throws Exception {
ClassLoader clazzloader = ClassLoader.getSystemClassLoader();
Class<?> clazz = clazzloader.loadClass("jvm.CL");
System.out.println("==================================");
System.out.println(clazz);
System.out.println("==================================");
clazz.newInstance();
System.out.println("==================================");
Class<?> clazz2 = Class.forName("jvm.CL");
System.out.println("==================================");
System.out.println(clazz2);
} }out:
==================================
class jvm.CL
==================================
class cl
==================================
==================================
class jvm.CL
3.HotSpot实现中用null代替根加载器Bootstrap
public class MyTest08 { public static void main(String[] args) {
ClassLoader classloader = ClassLoader.getSystemClassLoader();
System.out.println(classloader);
while(classloader!=null) {
classloader= classloader.getParent();
System.out.println(classloader);
}
} }//out:
sun.misc.Launcher$AppClassLoader@2a139a55
sun.misc.Launcher$ExtClassLoader@7852e922
null
4.数组的classloader,数组是JVM在运行时动态生成的类型,没有类加载器,如果调用getClassLoader会返回对应元素的类加载器。
public class MyTest09 { public static void main(String[] args) {
String[] strs = new String[2];
System.out.println(strs.getClass().getClassLoader()); System.out.println("============================"); MyTest09[] ms = new MyTest09[2];
System.out.println(ms.getClass().getClassLoader()); System.out.println("============================"); int[] ints = new int[2];
System.out.println(ints.getClass().getClassLoader());
} }//out:
null
============================
sun.misc.Launcher$AppClassLoader@2a139a55
============================
null
其中String类型的类加载器是Bootstrap 在HotSpot实现中被表现为null
源生类型则没有类加载器。
5.类加载器一般都会伴随一个安全管理器,来确保类加载过程中是安全的
JVM(三、双亲委派机制)的更多相关文章
- jvm双亲委派机制详解
双亲委派机制 记录一下JVM的双亲委派机制学习记录. 类加载器种类 当我们运行某一个java类的main方法时,首先需要由java虚拟机的类加载器将我们要执行的main方法所在的class文件 ...
- 深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题
一.概述 定义:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型.类加载和连接的过程都是在运行期间完成的. 二. 类的 ...
- JVM加载类的过程,双亲委派机制中的方法
JVM加载类的过程: 1)JVM中类的整个生命周期: 加载=>验证=>准备=>解析=>初始化=>使用=>卸载 1.1.加载 类的加载阶段,主要是获取定义此类的二进 ...
- 说一说JVM双亲委派机制与Tomcat
双亲委派模型与JVM 类加载 讲个故事: 以前,爱捣鼓的小明突然灵机一动,写出了下面的代码 package java.lang; public class String { //...复制真正Stri ...
- [转帖]说一说JVM双亲委派机制与Tomcat
说一说JVM双亲委派机制与Tomcat https://www.cnblogs.com/dengchengchao/p/11844022.html 讲个故事: 以前,爱捣鼓的小明突然灵机一动,写出了下 ...
- JVM类加载与双亲委派机制被打破
前言 前文已经讲了虚拟机将java文件编译成class文件后的格式:JVM虚拟机Class类文件研究分析 java文件经过编译,形成class文件,那么虚拟机如何将这些Class文件读取到内存中呢? ...
- 面试~jvm(JVM内存结构、类加载、双亲委派机制、对象分配,了解垃圾回收)
一.JVM内存结构 ▷ 谈及内存结构各个部分的数据交互过程:还可以再谈及生命周期.数据共享:是否GC.是否OOM 答:jvm 内存结构包括程序计数器.虚拟机栈.本地方法栈.堆.方法区:它是字节码运行时 ...
- JVM学习六:JVM之类加载器之双亲委派机制
前面我们知道类加载有系统自带的3种加载器,也有自定义的加载器,那么这些加载器之间的关系是什么,已经在加载类的时候,谁去加载呢?这节,我们将进行讲解. 一.双亲委派机制 JVM的ClassLoader采 ...
- JVM之类加载器、加载过程及双亲委派机制
JVM 的生命周期 虚拟机的启动 Java 虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实 ...
- 深入探究JVM之类加载与双亲委派机制
@ 目录 前言 类的生命周期 加载 验证 准备 解析 初始化 案例一 案例二 案例三 案例四 类加载器 类加载器和双亲委派模型 破坏双亲委派模型 第一次 SPI Tomcat OSGI 总结 前言 前 ...
随机推荐
- 番外:可刷新PDB的管理操作(如何切换PDB Switching Over)
基于版本:19c (12.2.0.3) AskScuti 主题:可刷新PDB如何进行切换操作 内容说明:本篇延续如何克隆可刷新的PDB(Refreshable PDB)一文,进行切换实验. 具体请参考 ...
- MFC在子线程中创建窗口(PostMessage方法)
1.创建子线程 C++创建线程的方式比较多 1)最简单易用的<thread>头文件,但是这种方法创建的子线程中无法给主线程PostMessage消息(也可能是我操作有误,总之没成功) 2) ...
- c# Gridview 自动分页功能 解决后面页面不显示问题
操作步骤: 操作如下: 1.更改GrdView控件的AllowPaging属性为true. 2.更改GrdView控件的PageSize属性为 任意数值(默认为10) 3.更改GrdView控件的Pa ...
- JavaScript的流程控制
JavaScript的流程控制 1.if...else if...else... 2.while 3.for 4.forEach 5.for...in... 完整代码如下: <!DOCTYPE ...
- spring(三):BeanFactory
- totensor方法和normalize方法 数值映射和归一化
totensor方法和normalize方法 数值映射和归一化 待办 ToTensor是指把PIL.Image(RGB) 或者numpy.ndarray(H x W x C) 从0到255的值映射到0 ...
- 请求响应状态status为canceled
发出ajax请求之后 发现status状态是canceled 1. 和form冲突 我的提交代码是这样的 $.ajax({ //几个参数需要注意一下 type: "POST",// ...
- java_爬虫_获取经过js渲染后的网页源码
md 弄了一天了……(这个月不会在摸爬虫了,浪费生命) 进入正题: 起初是想写一个爬虫来爬一个网站的视频,但是怎么爬取都爬取不到,分析了下源代码之后,发现源代码中并没有视频的dom 但是在浏览器检查元 ...
- CSS 盒子模型属性
盒子模型(Flexible Box) 属性 属性 说明 CSS box-align 指定如何对齐一个框的子元素 3 box-direction 指定在哪个方向,显示一个框的子元素 3 box-flex ...
- Ehab and a Special Coloring Problem
You're given an integer nn. For every integer ii from 22 to nn, assign a positive integer aiai such ...