文章目录

  • 第一部分 走进Java
  • 第二部分 自动内存管理机制
  • 第2章 Java内存区域与内存溢出异常
  • 2.1 概述
  • 2.2 运行时数据区域

  • 第三部分 虚拟机执行子系统
  • 第6章 类文件结构
  • 6.3 class类文件的结构
  • 6.3.1 魔数与Class文件的版本
  • 6.3.2 常量池
  • 6.3.3 访问标志
  • 第7章 虚拟机类加载机制
  • 7.1 概述
  • 7.2 类加载的时机
  • 7.3 类加载的过程
  • 7.3.1 加载
  • 7.3.2 验证


第一部分 走进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 加载

在加载阶段,虚拟机需要完成以下三件事情:

  1. 通过一个类的全限定名
7.3.2 验证

验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机本身的安全。