📚 残梦三生

记录技术成长,分享学习心得

← 返回首页

虚拟机类加载机制

分类:Java | 日期:2023-12-06

1 简介

Java的一门编译与解释并存的语言。其中编译指的就是将代码(.java)编译成虚拟机可以识别理解的字节码(.class),也就是所谓的Class文件。

而虚拟机的类加载机制,就是指虚拟机把描述类的数据从Class文件中加载到内存,并对数据进行校验、转换解析等操作,最后形成可以被虚拟机直接使用的Java类型的过程。

2 类加载过程

一个类型从被加载到虚拟机内存,再到卸载出内存为止,它的整个生命周期会经历加载、连接、初始化、使用和卸载五个阶段,其中连接里面又包含验证、准备和解析三个阶段。

2.1 加载

加载是整个类加载过程中的一个阶段。在这个阶段,虚拟机要经历三个阶段,第一阶段是通过一个类名获取该类的字节流;第二阶段是将字节流的静态存储结构转换为方法区的运行时数据结构;第三阶段是再内存中生成这类的java.lang.Class对象,作为方法区对这个类各种数据的访问入口。

2.2 连接

加载阶段和连接阶段的部分动作是交叉进行的,加载阶段没有完成,连接阶段可能已经开始了。

2.2.1 验证

验证是连接阶段的第一步。这一步需要确保Class文件的字节流中的信息符合规范要求,并且不会被当作代码运行后危害虚拟机安全。

验证阶段主要是对文件格式、元数据、字节码和符号引用进行验证。

2.2.2 准备

准备阶段是正式为类中定义的变量分配内存空间并设置变量初始值的阶段。不过需要注意的是,内存分配的仅仅包括类变量,不包括实例变量,实例变量会在对象实例化时随着对象一起分配在Java堆中,而且初始值都是默认值,而不是变量中定义的值。

2.2.3 解析

这个阶段是虚拟机将常量池内的符号引用替换成直接引用的过程。

2.3 初始化

类初始化是类加载过程中的最后一个步骤。到这一步,虚拟机才真正开始执行类中编写的Java程序。

3 类加载器

类加载器是实现类加载动作的工具,他在Java程序中的作用非常大。任意一个类都需要由加载它的类加载器和这个类本身一起共同确立它在Java虚拟机的唯一性,每一个类加载器都有一个独立的类名空间。也就是说,如果两个类是由两个不同的类加载器加载的,那么他们必然是不相同的。

3.1 双亲委派模型

在Java语言系统中,一共支持4类加载器,分别是启动类加载器、扩展类加载器、应用程序类加载器和自定义类加载器。双亲委派模型要求除了顶层的启动类加载器外,其他的类加载器都应该有自己的父类加载器。

双亲委派机制,其实就是如果一个类加载器收到了类加载的请求,他会向上反馈给自己的父类加载器去完成加载,所以一般都是由最顶层的启动类加载器完全加载请求。只有当父类反馈无法加载时,才会由子类其加载。

使用双亲委派机制的好处就是,通过双亲委派机制,无论是哪一个类加载器加载一个类,最终都会向上委派给启动类加载器去加载,这样就可以确保该类在各种类加载器环境中都能保证是同一个类。