「这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战」
接 JVM(一),我们看看常量池有什么 JVM中的常量池可以分成以下几类:
- Class文件常量池
- 全局字符串常量池
- 运行时常量池
每个Class文件的字节码中都有一个常量池,里面主要存放编译器生成的各种字面量和符号引用。 首先我们先了解一下class文件结构
一、 class文件结构
类型 | 名称 | 数量 |
---|---|---|
u4固定值(0xCAFEBABE) | Magic Number(魔数) | 1 |
u2(2个字节) | 次版本号 | 1 |
u2(2个字节) | 主版本号 | 1 |
u2(2个字节) | constant_pool_cout(常量个数) | 1 |
cp_info(N个字节) | constant_pool(常量池表) | constant_pool_cout-1 |
u2(2个字节) | access_flag(访问标记符号) | 1 |
u2(2个字节) | This class Name | 1 |
u2(2个字节) | super class name | 1 |
u2(2个字节) | Interfaces_count(接口数) | 1 |
u2(2个字节) | interfaces(接口名称) | Interfaces_count |
u2(2个字节) | fields_count | 1 |
field_info(n个字节) | fields_count | fields_count |
u2(二个字节) | methods_count(方法个数) | 1 |
method_info(N个字节) | 方法表 | methods_count |
u2(二个字节) | attruibute_count(附加属性 个数) | 1 |
attribute_info(n个字节) | attrubites(附加属性表) | attruibute_count |
1. 魔数(ca fe ba be)
它是class文件的头4个字节,用来表示这个class文件的类型
2. 次版本号(00 00)
3. 主版本号(00 37)
表示JDK11
4. 常量池的个数(00 15)
总共(21-1=20个),第0号常量被jvm给占用了表示什么都不引用
5. 常量池表
常量池长度不固定,因此常量池开头会有常量池的容量
6. class常量池分类:
- (1) CONSTANT_Utf8_info(字符串常量)
-
tag表示当前常量的类型,这里应该是1
-
length表示这个字符串的长度
-
bytes为这个字符串的内容(采用缩略的UTF8编码)
-
(2) CONSTANT_Integer_info
- (3) CONSTANT_Float_info
- (4) CONSTANT_Logn_info
- (5) CONSTANT_Double_info
- (6) CONSTANT_Class_info
- (7) CONSTANT_String_info
- (8) CONSTANT_Fielderf_info
- (9) CONSTANT_Methodref_info
- (10) CONSTANT_InterfaceMethodref_info
- (11) CONSTANT_NameAndType_info
二、 运行时常量池
运行时常量池是每一个类或者接口的常量池(Constant Pool)的运行时的表现形式
运行时常量池的作用是存储`class`文件常量池中的符号信息,在类的解析阶段会把这些符号引用转换成直接引用(实例对象的内存地址),翻译出来的直接引用也是存储在运行时常量池中。`class`文件常量池的大部分数据会被加载到运行时常量池
暂时我们先写到这里. . .