类的生命周期

类的生命周期

生命周期:加载 -> 连接 -> 初始化 -> 使用 -> 卸载

加载阶段

加载阶段主要完成以下两个步骤:

  • 加载类的字节码文件

    • 类加载器(Class Loader)负责从文件系统、网络或其他来源找到类的字节码文件(.class文件),并将其读入到JVM中。
    • 类加载器通常按需加载,即第一次使用该类时才加载。
  • 数据存储

    • 一旦字节码文件被读入JVM,它将被存储在方法区(Method Area)中。生成一个InstanceKlass对象,保存类的所有信息,里边还包含实现特定功能比如多态的信息。方法区是JVM内存中的一个逻辑区域,用于存储类结构信息,如字段、方法、构造函数等。
    • 在这个阶段,JVM会在堆中为这个类创建一个对应的java.lang.Class对象,作为方法区中这个类的各种数据的访问入口。对于开发者来说,只需要访问堆中的Class对象而不需要访问方法区中所有信息。 这样Java虚拟机就能很好地控制开发者访问数据的范围。

连接阶段

验证

连接(Linking)阶段的第一个环节是验证,验证的主要目的是检测Java字节码文件是否遵守了《Java虚拟机规 范》中的约束。这个阶段一般不需要程序员参与。

主要包含如下四部分:

  • 文件格式验证,比如文件是否以0xCAFEBABE开头,主次版本号是否满足当前Java虚拟机版本要求。
  • 元信息验证,例如类必须有父类(super不能为空)。
  • 验证程序执行指令的语义,比如方法内的指令执行到一半强行跳转到其他方法中去。
  • 符号引用验证,例如是否访问了其他类中private的方法等。

准备

准备阶段是连接阶段的第二步,它为类变量分配内存,并设置默认初始值。这些变量所使用的内存都在方法区中进行分配。准备阶段需要完成以下工作:

  • 分配内存:为类变量分配内存,这些变量不包括实例变量,实例变量会在对象实例化时随着对象一起分配在堆内存中。
  • 设置默认值:为类变量设置默认初始值,例如int类型的变量默认值为0,对象的引用默认值为null。(final修饰的基本数据类型的静态变量,准备阶段直接会将代码中的值进行赋值。)

解析

解析阶段是连接阶段的第三步,它是将类、接口、字段和方法的符号引用(字节码文件中使用编号来访问常量池中的内容)转换为直接引用(内存地址)的过程。

初始化阶段

  • 初始化阶段会执行静态代码块中的代码,并为静态变量赋值。执行流程与代码流程一致。
  • 初始化阶段会执行字节码文件中clinit部分的字节码指令。

请添加图片描述

以下几种方式会导致类的初始化:

  • 访问一个类的静态变量或者静态方法,注意变量是final修饰的并且等号右边是常量不会触发初始化。
  • 调用Class.forName(String className)。
  • new一个该类的对象时。
  • 执行Main方法的当前类。

java8中添加-XX:+TraceClassLoading 参数可以打印出加载并初始化的类

java8以上版本可添加-Xlog:class+load=info参数打印出加载并初始化的类

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林小果呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值