【JVM】类加载机制

Class 文件结构

Java 字节码文件主要包括以下几部分:

  • 魔数与class 文件的版本
  • 常量池
  • 访问标志:表示该 class 的属性和访问类型,该 class 是类还是接口,是不是 public,是否被 final 修饰
  • 类索引、父类索引、接口索引
  • 字段表属性:用于描述接口或类中描述的变量。比如变量的作用域(public、peivate),是否是静态变量(static),可变性(final),数据类型(基本类型、对象、数组)等等
  • 方法表属性:和字段表类似,描述的是方法的属性
  • 属性表属性:用于描述某些特定场景专有的信息

常量池

常量池主要存放两大类:字面量和符号引用。字面量类似于Java的常量的概念,如文本字符串,final常量等。符号引用包括以下三种:

  • 类和接口的全限定名
  • 变量的名称和描述符号
  • 方法的名称和描述符
    JVM 是在类加载阶段才开始进行动态链接的,也就是说这些字段和符号引用只有在运行期转换后才能获取真正的内存入口地址

Java 类加载机制

类加载主要分为三个阶段:加载、连接和初始化;连接阶段又可分为:验证、准备和解析

加载阶段:查找并加载类的二进制数据

加载阶段主做三件事情:

  • 通过类的全限定名来获取类的二进制字节流
  • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
  • 在 Java 堆中生成一个 java.lang.class 对象,作为对方法区中这些数据的访问入口
    加载阶段总结:查找并加载类的二进制数据,并在 JVM 堆中创建一个 class 对象,并且将类的信息保存至方法区

连接阶段

验证:验证是否符合 Java 规范和 JVM 的规范

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

准备:为类的静态变量分配内存,并初始化为默认值

准备阶段正式为变量分配内存并设置变量的初始值,这些内存都是在方法区中分配的。

  • 在准备阶段进行内存分配的只有类变量(static),实例变量会在对象实例化时随着对象在堆中一起分配内存
  • 在准备阶段为变量赋的初始值都是默认值(0, null, 0L, false)
解析:把类中的符号引用转换为直接引用

解析阶段是虚拟机将常量池内符号引用转换为直接引用的过程,符号引用包括类和接口的全限定名、变量的名称和描述符号、方法的名称和描述符。直接引用就是指向目标的指针。

初始化:为静态变量赋予正确的初始值

初始化阶段主要就是为静态变量赋予初始值

初始化时机:

  • 使用 new 创建类的实例
  • 访问类或接口的静态变量或对静态变量赋值
  • 访问类的静态方法
  • 反射
  • 初始化某个子类其父类也会初始化
  • 启动类

类加载器 类加载机制

类加载器

BootStrapClassLoader -> ExtClassLoader -> AppClassLoader -> User ClassLoader

类加载机制:双亲委派机制

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。

  1. 当 AppClassLoader 要加载一个 class 时,他首先不会自己尝试去加载这个类,而是将加载类的任务委托给父类 ExtClassLoader 去完成
  2. 当 ExtClassLoader 要加载一个 class 时,他首先不会自己尝试加载这个类,而是把类加载请求委托给 BootStrapClassLoader 去完成
  3. 如果BootStrapClassLoader加载失败(例如在$JAVA_HOME/jre/lib里未查找到该class),会使用ExtClassLoader来尝试加载;
  4. 若ExtClassLoader也加载失败,则会使用AppClassLoader来加载,如果AppClassLoader也加载失败,则会报出异常ClassNotFoundException。
相关推荐
一只叫煤球的猫5 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
bobz9656 小时前
tcp/ip 中的多路复用
后端
bobz9656 小时前
tls ingress 简单记录
后端
皮皮林5517 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
你的人类朋友7 小时前
什么是OpenSSL
后端·安全·程序员
bobz9658 小时前
mcp 直接操作浏览器
后端
前端小张同学10 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook10 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康11 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在11 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net