JVM 类加载机制

在这里插入图片描述

类的生命周期

类加载大致分为加载、验证、准备、解析、初始化五个阶段,其中加载、验证、准备、初始化顺序是固定的,解析的顺序不一定。它在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也成为动态绑定或晚期绑定)。并且这些阶段是顺序开始,而不是顺序执行或者完成,它们可能是交叉混合执行。
在这里插入图片描述

类加载

加载阶段的三个步骤:

  • 通过类型全限定名找到类的二进制字节流
  • 将字节流的静态存储结构转换为方法区运行时的数据结构
  • 在java堆中生成一个代表这个类的java.lang.Class对象,作为方法区的数据的入口
    在这里插入图片描述

连接

验证阶段

作用:确保加载类的正确性

这个阶段主要是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

  • 文件格式的验证: 对魔数和jdk版本、常量池中的常量是否有不被支持的类型等进行校验
  • 元数据验证:对字节码描述的信息进行语义分析
  • 字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。
  • 符号引用验证:确保解析动作能正确执行。

验证阶段非常重要,但不是必须,如果已经反复验证通过很多次,可以使用-Xverifynone 关闭大部分的类验证措施,以缩短虚拟机类加载的时间。

准备阶段

为类的静态变量分配内存,并将其初始化为默认值

  • 这里设置默认值仅类变量,不包括实例变量,实例变量会在类实例化时去分配
  • 初始化默认值只是分配数据类型的默认值,如00Lnullfalse
pulbic static int i = 3

现阶段设置默认值只会设置0, 而不是3,赋值为3应该在初始化阶段。

解析阶段

把类中的符号引用转换为直接引用

将常量池的符号引用转换为直接引用,一般包括 接口类字段类方法接口方法方法类型方法句柄以及调用点 限定符

直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。

初始化

对类的静态变量赋予真正的值。

在Java中对类变量进行初始值设定有两种方式:

  • 声明类变量是指定初始值
  • 使用静态代码块为类变量指定初始值
JVM初始化步骤
  • 类还没被加载和连接,就先加载类并连接类
  • 类的直接父类还没被初始化,就先初始化它的直接父类
  • 类中有初始化语句,则系统执行初始化语句
类初始化时机

只有对类主动使用时才会导致类的初始化

  • 直接创建实例,即new
  • 访问类或者接口的静态变量、对类的静态变量赋值
  • 调用类的静态方法
  • 反射
  • 初始化类的子类
  • Java虚拟机启动时被标明为启动类的类(Java Test),直接使用java.exe命令来运行某个主类

使用

类访问方法区内的数据结构的接口, 对象是Heap区的数据。

卸载

  • System.exit()
  • 正常执行结束
  • 异常终止
  • 系统异常导致java虚拟机停止

类加载器

类加载器的层级

在这里插入图片描述

  • 启动类加载器:负责加载存放在JDK\jre\lib下,或者通过-Xbootclasspath 路径下能够被虚拟机识别的类库(所有java.* 开头的类),启动类加载器不能直接被程序引用
  • 扩展类加载器:负责加载存放在JDK\jre\lib\ext下,或者通过java.ext.dirs 系统变量指定的路径下的所有类库,开发者可以直接使用扩展加载器。
  • 应用程序加载器:负责加载用户类路径(ClassPath)所指定的类,开发者可以直接使用该类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器

启动类加载器是通过c语言实现的,其他的加载器都是通过java实现。

类加载机制

  • 全盘负责 当一个类加载器加载一个class类时,这个class类的所有依赖或者引用的其他class都由它加载
  • 父类委托 先让父类加载器加载,只有当父类加载器无法加载该类时,才从自己的类路径中加载该类
  • 缓存机制 将加载过的类缓存起来,只有在缓存区找不到才去加载类,并放入缓冲区,这就是为什么修改了Class后,必须重启JVM,程序的修改才会生效
  • 双亲委托 当一个类加载器接收到类加载的请求时,先不去自己加载这个类,依次向上,交给父类加载器,最终都回到启动类加载器,如果还加载不了,再自己去加载
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值