doc: 文档阅读

This commit is contained in:
asahi
2025-12-17 17:54:42 +08:00
parent b579d930b2
commit bd8afa5895

View File

@@ -60,6 +60,18 @@
- [jstat](#jstat) - [jstat](#jstat)
- [jinfo](#jinfo) - [jinfo](#jinfo)
- [jstack](#jstack) - [jstack](#jstack)
- [类文件结构](#类文件结构)
- [魔数](#魔数)
- [class文件版本号](#class文件版本号)
- [常量池](#常量池)
- [类索引、父类索引、接口索引集合](#类索引父类索引接口索引集合)
- [字段集合](#字段集合)
- [方法集合](#方法集合)
- [属性表集合](#属性表集合)
- [虚拟机加载机制](#虚拟机加载机制)
- [类加载时机](#类加载时机)
- [加载](#加载)
- [验证](#验证)
# 深入理解java虚拟机 # 深入理解java虚拟机
@@ -542,3 +554,84 @@ jinfo -sysprops 5338
### jstack ### jstack
jstack命令用于生成虚拟机当前时刻的线程快照即当前虚拟机每一个线程正在执行的方法堆栈集合。该命令主要用于定位线程长时间出现停顿的原因例如线程间死锁、死循环、长时间等待等。 jstack命令用于生成虚拟机当前时刻的线程快照即当前虚拟机每一个线程正在执行的方法堆栈集合。该命令主要用于定位线程长时间出现停顿的原因例如线程间死锁、死循环、长时间等待等。
## 类文件结构
class是以字节为基础单位的二进制流各个数据项排列紧凑中间没有分隔符。当数据项实际占用的空间超过一个字节时多个字节之间按照`大端序`来进行排序,即高位字节在前。
class文件采用一种伪结构来存储数据该伪结构类似C语言中的结构体伪结构中只有两种数据类型
- 无符号数: 无符号数属于基本数据类型u1/u2/u4/u8分别代表长度为1/2/4/8个字节的无符号数无符号数可以用于描述数字、索引引用、数量值、utf-8编码的字符串值
- 表:表是由多个无符号数或其他表组成的复合数据类型,所有表都习惯性以`_info`结尾。
class文件本质上就是一张表其组成结构如下所示
| 类型 | 名称 | 数量 |
| :-: | :-: | :-: |
| u4 | magic | 1 |
| u2 | minor_version | 1 |
| u2 | major_version | 1 |
| u2 | constant_pool_count | 1 |
| cp_info | constant_pool | constant_pool_count -1 |
| u2 | access_flags | 1 |
| u2 | this_class | 1 |
| u2 | super_class | 1 |
| u2 | interfaces_count | 1 |
| u2 | interfaces | interfaces_count |
| u2 | fields_count | 1 |
| field_info | fields | fields_count |
| u2 | methods_count | 1 |
| method_info | methods | methods_count |
| u2 | attributes_count | 1 |
| attribute_info | attributes | attributes_count |
### 魔数
每个class文件的头4个字节被称为魔数其作用是确定该文件是否是一个能被虚拟机接受的class文件。class文件的魔数为`0XCAFEBABE`
### class文件版本号
魔数之后的4个字节记录的是class文件的版本号
- 第5、6个字节记录的是minor version次版本号
- 第7、8个字节记录的是major version主版本号
jdk的主版本号从45开始jdk 1.0/1.1使用了45的版本号而每个jdk大版本发布主版本号都会+1。并且jdk都能兼容以前版本的class文件。
### 常量池
在class主版本/次版本号之后,是常量池入口。
常量池中主要存放字面量和符号引用。
### 类索引、父类索引、接口索引集合
类索引this_class和父类索引super_class都是一个u2类型的数据接口索引集合(interfaces)则是一组u2类型的数据集合。
class文件通过上述3个字段来确定类的继承关系。
### 字段集合
字段表用于描述接口或类中声明的变量。字段field包括类级变量和实例级变量。
### 方法集合
方法集合中同样包含了静态方法和非静态方法。
### 属性表集合
属性表集合用于记录类的一些属性信息,如`final/SourceFile`等。
## 虚拟机加载机制
### 类加载时机
类从被加载到内存中开始,到类被卸载,其整个生命周期包含如下环节:
- 加载Loading
- 验证Verification
- 准备Preparation
- 解析Resolution
- 初始化Initialization
- 使用Using
- 卸载Unloading
其中,`验证、准备、解析`三个阶段统称为`链接`
### 加载
加载是类加载过程中的一个阶段,在加载阶段虚拟机主要执行如下步骤:
- 通过类的全限定类名来获取此类的二进制字节流
- 将该字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在内存中生成一个代表该类的`java.lang.Class`对象,作为方法区中这个类数据的访问入口
### 验证
验证是连接阶段的第一步这一阶段目的是为了确保class文件中字节流包含信息符合当前虚拟机的要求。