返回

大厂面试必知:虚拟机类加载机制详解(上)

后端

虚拟机类加载概述

在上一篇文章中,我们提到了在给对象分配内存之前需要经过类加载过程,类被虚拟机加载、解析、初始化后才会根据对象大小进行内存分配。那虚拟机是如何进行类加载、解析、初始化的呢?

类加载过程中虚拟机进行了诸多准备和操作,包括:

  • 检查是否需要对类进行加载
  • 获取类的二进制字节流
  • 将字节流解析成方法区结构
  • 在堆区生成与类相关的各种数据结构
  • 生成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虚拟机完成。