JVM架构图
本篇文章记录JVM架构的最上面一部分内容类加载子系统的知识点。
笔记来源: https://www.bilibili.com/video/BV1PJ411n7xZ
对应视频的章节:P27~P38
类的加载器及加载过程
类加载子系统作用:
类加载子系统负责从文件系统或网络中加载class文件,class文件在开头有一个特定的标识(CAFE BADY),ClassLoader只负责class文件的加载,文件是否可以运行由Execution Engine决定,加载的类信息存放在方法区,除此之外,方法区还存放了运行时常量池信息(数字常量和字符串字面量)
类的加载过程:
加载(Loading):
链接(Linking)
初始化:
几种类加载器
JVM支持两种类型的类加载器,一类是引导类加载器,一类是自定义类加载器。
派生于抽象类ClassLoader的加载器为自定义类加载器
代码演示:
/**
* 类加载器测试
*/
public class Demo001 {
public static void main(String[] args) {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//系统类加载器
System.out.println(systemClassLoader); //sun.misc.Launcher$AppClassLoader@18b4aac2
//扩展类加载器
ClassLoader extClassLoader = systemClassLoader.getParent();
System.out.println(extClassLoader); //sun.misc.Launcher$ExtClassLoader@61bbe9ba
//试图获取启动类加载器,获取不到
ClassLoader bootstrapClassLoader = extClassLoader.getParent();
System.out.println(bootstrapClassLoader); //null
//获取自定义类 的加载器,可见自定义类是通过 系统类加载器 加载的
ClassLoader classLoader = Demo001.class.getClassLoader();
System.out.println(classLoader); //sun.misc.Launcher$AppClassLoader@18b4aac2
//String类是通过引导类加载器加载的,Java的核心类库都是通过引导类加载器加载的
ClassLoader classLoader1 = String.class.getClassLoader();
System.out.println(classLoader1); //null
}
}
引导类(启动类)加载器:
c/c++语言编写的,加载Java核心库的类(rt.jar、resource.jar…)
扩展类加载器:
java语言编写的,加载jre/lib/ext下面的类,如果用户创建的jar放在此目录下也会由该加载器加载
系统类加载器:
java语言编写,负责加载环境变量classpath或系统属性下java.class.path下的类库。该类是程序中默认的类加载器,一般来说,系统中的类通过该加载器完成加载
为什么要使用用户自定义类加载器?具体实现步骤?
- 隔离加载类
- 修改类加载方式
- 扩展加载源
- 防止源码泄露
双亲委派机制
优势:
- 避免一个类被重复加载
- 避免核心api被修改