类的状态转化

java文件经过编译后转化为跨平台的二进制字节流,为class文件。
class定义了类接口的形式

在经过加载 连接和初始化过程后 可被运行时识别的类型和接口就在虚拟机中形成了。

class文件格式

magic魔数 固定OXcAFEBABE
minor_version 此版本
major_version 主版本
constant_pool_count 常量池个数
access_flags 访问标志
this_class 当前类
super_class 超类
interface_count
fieds_count 字段数量字段表
methods_count 方法数量
attributes_count 属性数量

常量池

常量池拥有class文件引用所有字符串常量,类名,接口名,字段名,方法名,其他字符信息。
指令的执行主要是依赖于常量池符号的引用。

常量池的定义是
cp_info{
ul tag
ul info[]
}

常量池容纳各种类型的字符信息
tag区分类型
决定了info[] 长度和结构

字段表
filed_info_fileds[]
描述如下信息
作用域
static
final
volatile
transient
类型 基本类型 对象或者数组
名称

方法表
method_info

access_flag

属性表

类的状态

HotSpot定义了7种状态
unparsble_by_gc 初始值 未解析
allocated 已分配,但未连接
loaded 已加载,并插入到jvm内部层次体系中,但尚未链接

linked已链接
being_initialized 初始化中
fully_initialized 完成初始化
initialization_error 初始化过程出错

Class字节流 读取出来 ,然后依次经过加载连接初始化这些逻辑阶段 才能成为jvm能够识别的格式成为可用状态。

执行顺序可变 HotSpot是将一些链接过程放在了加载之前的

例如对class 魔术和版本信息在加载过程中读取的信息随便就验证了。

类的加载连接初始化过程如下
类的加载链接状态转换图

加载过程:
从.class 文件读取字节流,并按照虚拟机对class文件格式解析出来类或接口的二进制描述格式。并创建相应的类或者接口。
链接让虚拟机运行时有效的识别类或者接口类型的过程
分为验证 二进制表示结构正确
准备 为类接口的静态字段分配空间 并采用默认值初始化这些字段
解析 将符号引用转化为直接引用的过程
他们之间的顺序没有强制规定

初始化是执行类或接口的初始化方法

完成上述步骤的JAVA 类型可以在jvm中使用了

跟踪类的加载过程

性能统计
运行时监控数据 运行时计数器 计数器以.分割 的前缀成为命名空间
这个后续再讲

加载 从Class字节流文件中读取类型信息
HotSpot中的Classfile模块为虚拟机提供加载功能
包括
verifier classloader symbolTable ClassFileParser SystemDirectionary
初始化阶段 将初始化与类相关的一些perfData计数器。
搜索lib库

加载基于类解析器 类解析器利用ClassfileStream 读取Class文件字节流
(1)首先读取魔数
(2)读取Class文件的主次版本 及验证
(3)读取常量池 返回常量池句柄 接下来对this类型和super类的解析还要用到运行时常量池信息。
(4)读取访问标志
(5)访问当前索引 并按索引在 常量池中找到当前类的全限定名
(6)读取父类索引
。。。
(13)通知类已加载更新perfData计数器

加载完成后 虚拟机在方法区中建立了类元数据 当需要时可以根据类元数据创建类的实例 访问类变量和调用类的方法
具体在ClassFileParser类的ParserClassFile函数

这一步形成了很多的class文件 通过符号引用来建立密切的联系

符号引用是字符串的形式存在的
每个class文件中都有一个常量池 存放符号引用
加载后形成 运行时常量池 区别于静态常量池

把符号引用可以转化为直接引用 可以获得准确的内存实体

符号引用转为直接引用的过程为解析 也成为常量池解析 是链接的核心

早解析 在主方法执行前一次完成对所有的解析
HotSpot使用的是在符号引用首次被访问时采取解析 (晚解析)

HotSpot设置了延迟的最低容忍度至少在类型初始化前确保已链接
若不是
instanceKlass 定义了链接过程 link_class_impl()拥有这具体的连接过程可分为一篇单独来讲

验证
确保类接口的二进制信息是有效的。
method主要目标
验证范围
方法控制权限
参数和静态类型检查
堆栈滥用
变量是否初始化
变量赋值类型
异常表达必须引用合法指令
验证局部变量表‘
逐一验证每个字节码的合法性

在Verifier模块实现了验证

2准备
为类讲台变量分配空间并初始化

3,解析过程将四类符号引用转化为直接引用 运行时的实际内存
类 接口 字段 类方法或者接口方法
优化解析器性能
常量池添加 缓存项 constantPoolCache 原本的索引位置也会调整

初始化过程
执行类或者接口的初始化方法

初始化触发条件
1.jvm遇到需要引用类或者接口的指令 new getstatic putstatic invokestatic
2.初次调用MethodHandle实例时返回REF_getstatic 等的句柄时
3.调用反射方法时
4.初始化类的子类
5类被设计为jvm启动时的初始类

在instanceKlass类中设计了初始化过程 initialize_impl()。必须经过验证和准备 有可能已经解析过
link_class实现过程

虚拟机支持多线程 类的初始化过程还要做好同步
具体的在initialize_impl()中哦后面有机会写成独立的一片

类的族谱略

系统字典略

写完了类的状态转化 下一节开始写创建对象的过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值