大厂面试必知:虚拟机类加载机制详解(上)
2023-12-25 14:17:32
虚拟机类加载概述
在上一篇文章中,我们提到了在给对象分配内存之前需要经过类加载过程,类被虚拟机加载、解析、初始化后才会根据对象大小进行内存分配。那虚拟机是如何进行类加载、解析、初始化的呢?
类加载过程中虚拟机进行了诸多准备和操作,包括:
- 检查是否需要对类进行加载
- 获取类的二进制字节流
- 将字节流解析成方法区结构
- 在堆区生成与类相关的各种数据结构
- 生成Java虚拟机内部所使用的常量池并将其放入方法区
- 校验类的正确性
- 为类创建一个用于执行的java.lang.Class对象,作为方法区类的各种数据的访问入口
Java虚拟机类加载器
类加载器(ClassLoader)是Java虚拟机用于加载类的一类特殊实例,也是Java类加载子系统的一个基础组成部分,它负责将存储在Class文件(文件后缀为.class)中的Java字节码加载到Java虚拟机中。
类加载器通常由Java虚拟机实现,根据不同的类加载器,Java虚拟机将类加载请求分配给不同的类加载器去处理。Java虚拟机中包含多种类型的类加载器,常见的有以下四种:
1. 启动类加载器(Bootstrap ClassLoader)
启动类加载器是Java虚拟机中最早也是最重要的类加载器,它负责加载Java虚拟机运行所必须的类,如rt.jar中的类。启动类加载器是Java虚拟机的一部分,由Java虚拟机实现,因此无法直接在Java程序中访问。
2. 扩展类加载器(Extension ClassLoader)
扩展类加载器负责加载Java虚拟机安装目录中的扩展库中的类,如lib/ext目录下的类。扩展类加载器由Java虚拟机实现,因此无法直接在Java程序中访问。
3. 系统类加载器(System ClassLoader)
系统类加载器负责加载Java应用程序的类路径中的类。系统类加载器由Java虚拟机实现,因此无法直接在Java程序中访问。
4. 用户自定义类加载器(User-Defined ClassLoader)
用户自定义类加载器是Java程序员自定义的类加载器,它用于加载Java程序中的类。用户自定义类加载器可以继承java.lang.ClassLoader类,并重写父类的loadClass()方法实现自己的类加载逻辑。
Java虚拟机类加载过程
Java虚拟机将类的加载过程分为四个步骤:
1. 加载(Loading)
加载步骤负责将Class文件从文件系统或网络加载到内存中。加载步骤由类加载器负责完成。
2. 链接(Linking)
链接步骤负责对加载后的类进行链接操作,包括:
- 验证:验证类是否符合Java虚拟机的规范,包括字节码的格式、类结构是否正确等。
- 准备:为类的静态变量分配内存并将其初始化为默认值。
- 解析:将类的符号引用转换为直接引用。
链接步骤由Java虚拟机完成。
3. 初始化(Initialization)
初始化步骤负责对类的静态变量进行初始化,包括:
- 给类的静态变量分配内存
- 将类的静态变量初始化为指定的初始值
初始化步骤由Java虚拟机完成。
4. 卸载(Unloading)
卸载步骤负责将不再使用的类从内存中卸载。卸载步骤由Java虚拟机完成。