【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。
相关推荐
简 洁 冬冬20 分钟前
Java中的Servlet
java·开发语言·servlet
fly spider29 分钟前
多线程-线程池的使用
java·面试·线程池·多线程·juc
组合缺一44 分钟前
Solon Cloud Gateway 开发:导引
java·gateway·reactor·solon·响应式
计算机-秋大田1 小时前
基于微信小程序的英语学习交流平台设计与实现(LW+源码+讲解)
spring boot·后端·学习·微信小程序·小程序
matlabgoodboy1 小时前
留学生scratch计算机haskell函数ocaml编程ruby语言prolog作业VB
开发语言·后端·ruby
陈平安Java and C2 小时前
二叉树介绍
java
S-X-S2 小时前
sunrays-framework配置重构
java·重构
gentle coder2 小时前
JVM_类的加载、链接、初始化、卸载、主动使用、被动使用
java·jvm
釉色清风3 小时前
【数据结构】动态内存管理函数
java·c语言·javascript·数据结构·c
桦说编程3 小时前
如何安全发布 CompletableFuture ?Java9新增方法分析
java·性能优化·函数式编程·并发编程