类加载器我们都知道有如下的继承结构,这个关系只是逻辑上的父子关系。

我们一直听说引导类加载器没有实体,为什么没有实体呢?

因为引导类加载器只是一段C++代码并不是什么实体类,所谓的引导类加载器就是那一段C++逻辑,让JVM从C++代码转到Java代码来加载其它类。

一:引导类加载器/启动类加载器到底是啥?

JVM启动后要找我们的Main Class,在openJDK中有一个java.c的C++文件

在这个文件中我们可以看到JVM是怎么加载mainClass的。

在第二步中,会调用cls的checkAndLoadMain方法,那这个cls是什么东西?GetLauncherHelperClass返回是个什么? 我接着看。

关键点来了。FindBootStrapClass 通过动态链接库加载需要的类。加载到sun/launcher/LauncherHelper  类。

启动类加载器就是上面这个逻辑,主要目的就是找到sun/launcher/LauncherHelper 这个类。找到这个类之后再去创建扩展类加载器,应用类加载器。

我们回到上面的第二步,知道cls就是LauncherHelper了。看下这个类里面的checkAndLoadMain方法,这个类在rt.jar包里面。

a处我们的看到通过ClassLoader.getSystemClassLoader()得到一个类加载器。在c处通过这个类加载器加载MainClass。

这个MainClass怎么得到的可以从b处看到,我们如果自己需要获取jar的相关信息可以参考里面的逻辑方法,具体内容不再探讨。

那么我们就去看下a处的这个类加载器是那个?

sc1是由Launcher.getLauncher()中的getClassLoader()得到的。

我们看this.loader是怎么赋值的。

终于看到们熟悉的东西了!!!   原来扩展类加载器ExtClassLoader和应用类加载器AppClassLoader都是Launcher的内部类。

二:扩展类加载器ExtClassLoader创建

首先我们看到扩展类加载器继承URLClassLoader。其加载的路径是系统变量java.ext.dirs。 在第三步构造函数里面我们看到创建扩展类加载器的时候第二个参数传入的就是null,这个参数就是父类构造器。

这下我们知道为啥在项目中获取扩展类加载器父加载器的时候得到的为空了。

三:系统类加载器创建

从上面得到AppClassLoader的时候把扩展类加载器作为参数传了进去。

系统类加载器加载的路径是系统参数为:java.class.path路径。创建它的时候把扩展类加载器作为父类传了进去。

上面把得到的系统类加载器设置为了线程上下文的类加载器。这一点很重要。

到此我们从代码的角度看到引导类加载器,扩展类加载器,系统类加载器是怎么维护他们之间的逻辑关系的。他们的这种关系也是双亲委派的基础也是打破双亲委派的切入点。

关于类加载器加载的路径,可以通过下面的代码输出看到。


四:双亲委派

当使用一个类加载器进行 classLoader.loadClass(String name)的时候都会走到下面的这个逻辑。(记住这个方法是protected的,前提是自定义类加载器不重写这个方法)

1:检查需要加载的class是否已经加载了,如果加载过了直接返回。

2:如果没有加载过,先看父加载器是否为空,(这个parent参数在创建类加载器的时候当做参数传进来的,上面内容已经说过。),不为空的话让父类加载器尝试加载。父类加载器还有父类加载器就传递上去加载。

3:直到父类加载器为空,即到扩展类加载器,parent为空,就调用native方法通过动态链接通过C++代码来加载,还记得上面FindBootStrapClass 吗 ,就是它来加载的。

4:当所有父类加载不到的时候就走到findClass(name)了,这也是个protected的,需要自定义类加载来实现加载方法。也就是所说的父类加载不到才由自己加载。

下一节记录怎么打破双亲机制。

JVM(三)从JVM源码角度看类加载器层级关系和双亲委派的更多相关文章

  1. 从JDK源码角度看Short

    概况 Java的Short类主要的作用就是对基本类型short进行封装,提供了一些处理short类型的方法,比如short到String类型的转换方法或String类型到short类型的转换方法,当然 ...

  2. 从JDK源码角度看Byte

    Java的Byte类主要的作用就是对基本类型byte进行封装,提供了一些处理byte类型的方法,比如byte到String类型的转换方法或String类型到byte类型的转换方法,当然也包含与其他类型 ...

  3. 从JDK源码角度看Boolean

    Java的Boolean类主要作用就是对基本类型boolean进行封装,提供了一些处理boolean类型的方法,比如String类型和boolean类型的转换. 主要实现源码如下: public fi ...

  4. 从JDK源码角度看Object

    Java的Object是所有其他类的父类,从继承的层次来看它就是最顶层根,所以它也是唯一一个没有父类的类.它包含了对象常用的一些方法,比如getClass.hashCode.equals.clone. ...

  5. 从template到DOM(Vue.js源码角度看内部运行机制)

    写在前面 这篇文章算是对最近写的一系列Vue.js源码的文章(https://github.com/answershuto/learnVue)的总结吧,在阅读源码的过程中也确实受益匪浅,希望自己的这些 ...

  6. Android布局性能优化—从源码角度看ViewStub延迟加载技术

    在项目中,难免会遇到这种需求,在程序运行时需要动态根据条件来决定显示哪个View或某个布局,最通常的想法就是把需要动态显示的View都先写在布局中,然后把它们的可见性设为View.GONE,最后在代码 ...

  7. 从JDK源码角度看java并发的原子性如何保证

    JDK源码中,在研究AQS框架时,会发现很多地方都使用了CAS操作,在并发实现中CAS操作必须具备原子性,而且是硬件级别的原子性,java被隔离在硬件之上,明显力不从心,这时为了能直接操作操作系统层面 ...

  8. 从源码角度看JedisPoolConfig参数配置

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 你好,JedisPoolConfig Java中使用Jedis作为连接Redis的工具.在使用Jedis的也可以配置Jed ...

  9. 从源码角度看 PHP 字符串类型转换

    PHP 的类型转换是比较方便的,但是越是容易使用的东西,底层的实现越是复杂,而且在使用中像我这样的新手也往往不清楚转换后的结果到底是什么.有时候,对于 Java 这种强类型的语言,使用的时候需要强制进 ...

随机推荐

  1. post 和php://input

    $_POST['paramName'] 获取通过表单(multipart/form-data)提交的数据.但有时客户端会直接将请求数据以字符串的形式都放到 body 里传递过来,那么服务端就需要使用  ...

  2. 使用Github快速的寻找项目

    作为一个3年的码农昨天在学习项目,顺便总结一下 ,在Github找项目的几个常用方式 ,如果对您有帮助,可以点个关注,便于下次光顾! 首先我们来看一下常用命令 1.指定搜索方式 搜索文件中有spiri ...

  3. Python编程基础:循环结构

    一.为什么要用循环 现在有一个任务,要求你输出一百遍"好好学习,天天向上!",想一想,你会怎么做? (一)老老实实的笨方法 print("第1遍写:好好学习,天天向上!& ...

  4. Python稳基修炼之异常处理

    错误与异常 1.区分错误与异常 两种错误(都必须改正): 语法错误(代码不规范,格式不对或缺少符号).逻辑错误(逻辑不通) 异常: 程序运行时发生错误的信号 2.异常处理与注意事项 异常处理: 程序员 ...

  5. 短链接服务Octopus的实现与源码开放

    前提 半年前(2020-06)左右,疫情触底反弹,公司的业务量不断提升,运营部门为了方便短信.模板消息推送等渠道的投放,提出了一个把长链接压缩为短链接的功能需求.当时为了快速推广,使用了一些比较知名的 ...

  6. idea中Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.

    我本机安装的mysql版本是5.7的,那么IDEA要连接mysql也应该匹配下驱动版本.把Driver改成MySQL for 5.1就可以了 在点击Test Connection测试下,成功啦!

  7. 这4种ThreadLocal你都知道吗?

    什么是ThreadLocal ThreadLocal类顾名思义可以理解为线程本地变量.也就是说如果定义了一个ThreadLocal, 每个线程往这个ThreadLocal中读写是线程隔离,互相之间不会 ...

  8. 【代码周边】Idea设置类注解和方法注解(带图)

    Idea版本: 类注解 打开setting→Editor→Code Style→File and Code Templates /** * Created with IntelliJ IDEA. * ...

  9. 浅谈ES6数组及对象的解构

    一.数组的解构,ES6的新特性,主要是方便操作数组,节省不必要的代码,提高代码质量. 上图例子中, example1: 之前想要获取数组中的值,只能挨个获取下标,然后取值 example2:ES6新特 ...

  10. Kafka知识总结及面试题

    目录 概念 Kafka基础概念 命令行 Kafka 数据存储设计 kafka在zookeeper中存储结构 生产者 生产者设计 消费者 消费者设计 面试题 kafka设计 请说明什么是Apache K ...