文章目录
第一部分 走进Java
第二部分 自动内存管理机制
第2章 Java内存区域与内存溢出异常
2.1 概述
2.2 运行时数据区域
第三部分 虚拟机执行子系统
第6章 类文件结构
字节码文件对应Class文件
6.3 class类文件的结构
Class文件是一组以8位字节为基础单位的二进制流,各个数据项目按顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。
Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表,后面的解析都要以这两种数据类型为基础。
无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节…,可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。
表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表都习惯性地以_info结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表。
6.3.1 魔数与Class文件的版本
每个Class文件的头4个字节称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。
第5和第6个字节是次版本号(Minor Version),第7和第8个字节是主版本号(Major Version)。Java的版本号是从45开始的,JDK1.1之后的每个JDK大版本发布主版本号向上加1
6.3.2 常量池
紧接着主次版本号之后的是常量池入口,常量池可以理解为Class文件之中的资源仓库,它是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时它还是在Class文件中第一个出现的表类型数据项目。
常量池入口需要放置一项u2类型的数据,代表常量池容量计数值。常量池中主要存放两大类常量:字面量和符号引用。常量池中每一项常量都是一个表,这些表都有一个共同的特点,就是在表开始的第一位是u1类型的标志位,代表当前这个常量属于哪种常量类型。
6.3.3 访问标志
常量池结束后,紧接着的两个字节代表访问标志(access_flags)
第7章 虚拟机类加载机制
7.1 概述
虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。
7.2 类加载的时机
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)
7.3 类加载的过程
7.3.1 加载
在加载阶段,虚拟机需要完成以下三件事情:
- 通过一个类的全限定名
7.3.2 验证
验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机本身的安全。