JVM类加载
目录
- 前言
- 1. 类加载过程
- 1.1 加载
- 1.2 验证
- 1.3 准备
- 1.4 解析
- 1.5 初始化
- 2. 双亲委派模型
- 总结
前言
JVM的意思是Java虚拟机,是Java运行的基础,其中执行流程中有个过程叫做类加载,本篇文章就来介绍类加载。
1. 类加载过程
类加载分为以下几个步骤:加载、连接(验证、准备、解析)、初始化。下面将以加载、验证、准备、解析、初始化这五个步骤进行讲述。
1.1 加载
首先根据代码中编写的“全限定类名”(包名+类名,例如java.lang.String),找到“.class”文件,找的过程称为“双亲委派模型,在下面会讲述”;然后打开文件,读取文件到内存中;最后进行数据格式的解析。
1.2 验证
校验上述的.class"中读取的内容,是否合法。假设你拿一个图片的二进制文件,后缀改为".class",此时读取的内容就是不合法的。在验证过程中,如果发现某个地方的格式存在问题,就需要及时报错。
1.3 准备
给类对象分配内存空间。类加载最终得到的结果则是内存中的“类对象”。这里分配的空间,是一个未初始化的内存空间,具体来说,空间上的每个字节都是"0"。
1.4 解析
针对代码中的常量进行初始化。在“.class”文件中,也会涉及到一些常量,这也是需要放到内存中的,所以也需要对常量进行初始化,方便加载到内存中。
1.5 初始化
开始执行类中编写的Java程序代码。类的静态成员执行真正的初始化操作,静态代码块执行,同时还有父类/需要实现的接口的加载。
2. 双亲委派模型
JVM中进行类加载的操作,需要依赖内部的模块,叫做类加载器(class loader),在进行类加载时,首先需要找到对应的类。JVM自带了三种类加载器:Bootstrap ClassLoader(负责在Java标准库中查找)、ExtensionClassLoader(负责在Java的扩展库中查找)、ApplicationClassLoader(负责在Java第三方库/当前项目进行查找)。
在这三个类加载器之间,存在“父子关系”,都有一个parent这样的属性,保存了自己的父亲是谁(BootstrapClassLoader>ExtensionClassLoader>ApplicationClassLoader。
假设要加载一个类java.lang.String,调用的入口是ApplicationClassLoader,拿到任务后,先把任务抛给父亲,最后会抛给ApplicationClassLoader,搜索自己负责的目录(标准库目录),发现能找到,就继续后续的加载流程。
如果ApplicationClassLoader没有找到,就将任务抛回ExtensionClassLoader,如果还没有找到,继续抛回BootstrapClassLoader,如果还没有找到,就会抛出异常ClassNotFoundException。
双亲委派模型也是可以打破的,在特定场景下,程序员可以实现自己的类加载器,这种自己实现的类加载器可以自行判断是否要遵守双亲委派模型。
总结
本篇文章介绍了JVM类加载的基本流程,同时介绍了加载阶段的双亲委派模型。希望大家看完之后能对类加载的过程有所了解。