丰县做淘宝网站东莞市网站建设品牌
JVM
本文链接:https://blog.csdn.net/feather_wch/article/details/132116849
类文件结构
1、class文件的组成
- 无符号数:基本数据类型 u1 u2 u3 u4 描述 
- 数字
 - 字符串
 - 索引引用
 
 - 表:复合数据类型,无符号数 + 表组, _info结尾
 
2、class文件是大段字节序
方便阅读
3、class文件的组成部分
- 魔数
 - 版本号
 - 常量池
 - 访问标志
 - 类索引
 - 父类索引
 - 接口索引集合
 - 字段表集合
 - 方法表集合
 
// 魔数 咖啡
// 版本号
// 常量池
// 访问标志
// 类索引,父类索引,接口索引集合
final class Man extends Person implements IEat, ISleep{public static final String YEAR = "2023"String name; // 字段表集合public void talk(){ // 方法表集合//}
}
 
4、魔数是什么?
- 0xCAFEBABY 咖啡宝贝
 - 4byte
 
5、版本号
- 次版本号:儿子在前 // 质子
 - 主版本号:爸爸在后 // 纣王
 
常量池
6、常量池 = 入口 + 常量池
- 入口:u2,= 多少个常量
 - 常量池:1个常量 = 1个表, 
- 17种表 = U1 tag + 独立的结构
 
 
7、常量池中存放的内容
- 字面量(常量值,String)
 - 符号引用 
- 类和接口的名称
 - 方法的名称和描述符,描述符()Ljava/lang/String;
 - 字段的名称和描述符,描述符Ljava/lang/Object;
 - 方法句柄和方法类型
 - 动态调用点和动态常量
 
 
8、方法的描述符 ==> JNI方法描述符
方法的参数类型和返回类型
9、JNI中方法描述符(Method Descriptor)
- 唯一地标识一个方法
 - 一个方法描述符为:(Ljava/lang/String;I)V 表示该方法有两个参数,分别为String类型和int类型,返回值类型为void。
 
10、JVM中方法句柄和方法类型是指什么? ===> 反射机制
- 方法句柄(MethodHandle):可以看作是一个轻量级的函数指针,用于表示对方法的调用。
 - 方法类型(MethodType)描述了方法的参数类型和返回类型。
 - 两者通常一起使用:
 
Person person = new Person();
MethodType methodType = MethodType.methodType(void.class);
MethodHandle methodHandle = MethodHandles.lookup().findVirtual(Person.class, "sayHello", methodType);
methodHandle.invokeExact(person);
 
11、JVM中的动态调用点
- 指的是在程序运行时根据实际对象类型来确定要调用的方法。这种调用方式称为【动态分派】 ===> JVM 方法调用
 - 动态调用点通常发生在针对多态类型的方法调用中。
 - 动态调用点的确定是在运行时发生的,使用了虚方法表(virtual method table)来存储对象的方法信息,以便在运行时进行动态分派。 
- 在虚方法表中,每个方法对应一个偏移量,通过偏移量可以找到对应的方法实现。 ===> 虚方法表
 
 
12、JVM中的动态常量
- 运行时才确定常量的数值
 - 有性能开销
 
public class Main {public static final int MAX_VALUE = calculateMaxValue();public static int calculateMaxValue() {// 这里可以是一些复杂的逻辑来计算最大值return 100;}public static void main(String[] args) {System.out.println("最大值:" + MAX_VALUE);}
}
 
访问标志-access_flags
- class是类、接口、注解还是枚举
 - 是否是public、abstract等
 
类索引
1、类索引是什么?
- 用于到常量池中寻找:类的全限定名
 
父类索引
- U2
 - 用于到常量池中寻找:父类的全限定名
 
接口索引集合
- 入口 + 索引表集合(U2集合)
 - 用于到常量池中寻找:接口的全限定名
 
字段表集合
- 入口 + 字段表
 - 描述类和接口中声明的字段
 - 字段表中每一项包含的内容 
- 访问标志
 - 名称索引 -> 常量池中
 - 描述符索引 -> 常量池中
 - 属性表集合 = 入口 + 属性表 
- 举例:final static int a = 123, 在属性表中会有COnstantValue属性 ===> 类加载阶段
 
 
 
方法表集合
- 入口 + 方法表
 - 访问标志 + 名称索引 + 描述索引 + 属性表集合
 
2、特征签名是什么?
- 方法重载的时候,Java中特征签名 = 方法参数在常量池中符号引用的集合
 - class中特征签名 = 返回值 + 方法参数在常量池中符号引用的集合
 
属性表
1、属性表的主要属性 ===> APT ===> ASM
- Code
 - Exception 
- 和异常表不同 ===> ?
 - 展示方法需要检查哪些异常
 
 - ConstantValue ===> 类加载机制,准备阶段
int x = 123; // <init()>实例构造方法中赋值 static int x = 123; // <clinit>类构造器中赋值 final static int x = 123; //ConstantValue属性,在【准备阶段】赋值 
2、Code属性的结构
- 属性名
 - 属性长度
 - 操作数栈最大深度
 - 局部变量表的存储空间(slot为单位):不等于局部变量表最大值,会复用
 - 字节码长度:总长度
 - 字节码指令:多个指令 
- aload_0、invokespecial、init等指令
 
 - 异常表 
- start_pc
 - end_pc
 - catch_type
 - handler_pc
 
 
