类加载及双亲委派模型(一)
初衷 类加载相关的文章网上也有很多,简单搜一下就吧啦吧啦大堆内容,那为什么我会选择这样一个主题内容去详细描述呢?正如我开这个个人博客的初衷,这是一个记录个人技术积累和实践的小窝。然后,也希望大家可以从文章中温故而知新,有所收获。接下来,我们花两个篇幅的内容,来深入了解java类加载机制。
个人博客网址:https://dingzf.top
谢谢读者的驻留,也欢迎大家邮箱联系我来技术交流。([email protected])
一. 概述
虚拟机把描述类的数据从Class文件加载到内存中,并对数据进行校验、转换解析和初始化,最终变成可以被虚拟机直接使用的java类型,即Class对象,这就是虚拟机的类加载机制。
二. 类加载过程
类从被加载到虚拟机内存中开始,到卸载出内存为止,他的生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)。
2.1类加载的时机
什么情况下需要开始类加载过程的第一个阶段:加载?java虚拟机没有进行强制约束,但是对于初始化阶段,虚拟机规范规则严格规定了有且只有以下5种情况必须立即对类进行初始化(而加载、验证等过程必然在此之前开始):
- 遇到new 、getstatic、putstatic、invokestatic这4条字节指令时,如果类没有进行过初始化,则需要先触发其初始化。
- 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
- 当初始化一个类的时候,其父类还没有进行过初始化,先触发其父类初始化。
- 虚拟机启动时,优先触发主类(包含**main()**方法的那个类)初始化
- 如果一个java.lang.invoke.MethodHandle的方法句柄,其对应的类没有进行过初始化,则需先触发其初始化
2.2类加载过程详解
三.类加载器双亲委派模型
3.1双亲委派模型的工作过程
如果一个类加载器收到类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器完成。每个类加载器都是如此,只有当父加载器在自己的搜索范围内找不到指定的类时(即ClassNotFoundException),子加载器才会尝试自己去加载。
3.2双亲委派模型层次关系
- 启动类加载器(Bootstrap ClassLoader):由C++语言实现(针对HotSpot),负责将存放在<JAVA_HOME>\lib目录或-Xbootclasspath参数指定的路径中的类库加载到内存中。
- 扩展类加载器(Extension ClassLoader):负责加载<JAVA_HOME>\lib\ext目录或java.ext.dirs系统变量指定的路径中的所有类库。
- 应用程序类加载器(Application ClassLoader)。负责加载用户类路径(classpath)上的指定类库,我们可以直接使用这个类加载器。一般情况,如果我们没有自定义类加载器默认就是用这个加载器。
本篇幅我们了解了类加载过程及双亲委派模型,下一篇幅,我们通过代码详细解读如何破坏双亲委派模型及osgi的深入探究。