JVM虚拟机-Class文件之常量池

简介: JVM虚拟机-Class文件之常量池

 

一、常量池的作用

在class文件中的魔数、副版本号、主版本之后,紧接着就是常量池的数据区域了,如下图用红线包括的位置:

image.gif编辑

常量池可以比喻为Class文件里的资源仓库,它是Class 文件结构中与其他项目关联最多的数据,通常也是占用Class文件空间最大的数据项目之一,另外,它还是在Class文件中第一个出现的表类型数据项目。

二、常量池的结构

常量池的结构比较简单,前面的两个字节叫做常量池计数器(constant_pool_count),它记录了常量池项(cp_info)的个数。后面紧接着就是constant_pool_count-1常量池项(cp_info)。这跟报文通信协议比较类似,首先定义报文的大小,接着就是对应大小的报文内容。

image.gif编辑

image.gif编辑

由于常量池中常量的数量是不固定的,所以在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值(constant_pool_count)。与Java中语言习惯不同,这个容量计数是从1而不是0开始的,如上图所示,常量池容量(偏移地址:0x00000008)为十六进制数0x0021,即十进制的33,这就代表常量池中有33项常量,索引值范围为1~33。在Class文件格式规范制定之时,设计者将第0项常量空出来是有特殊考虑的,这样做的目的在于,如果后面某些指向常量池的索引值的数据在特定情况下需要表达“不引用任何一个常量池项目”的含义,可以把索引值设置为0来表示。Class文件结构中只有常量池的容量计数是从1开始,对于其他集合类型,包括接口索引集合、字段表集合、方法表集合等的容量计数都与一般习惯相同,是从0开始。

三、常量池的分类

常量池中主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References)。字面量比较接近于Java语言层面的常量概念,如文本字符串、被声明为final的常量值等;而符号引用则属于编译原理方面的概念。具体分类如下图:

image.gif编辑

常量池中每一项常量都是一个表,最初常量表中共有11种结构各不相同的表结构数据,后来为了更好地支持动态语言调用,额外增加了4种动态语言相关的常量,为了支持Java模块化系统 (Jigsaw),又加入了CONSTANT_M odule_info和CONSTANT_Package_info两个常量,所以截至JDK 13,常量表中分别有17种不同类型的常量。这17类表都有一个共同的特点,表结构起始的第一位是个u1类型的标志位(tag,取值见下表中标志列),代表着当前常量属于哪种常量类型。

官网最新:Specification for JEP 309: Dynamic Class-File Constants (JROSE EDITS)

image.gif编辑

image.gif编辑

我们对这个class文件进行分析,可以看到前8个字节是该class文件的魔数和版本号,紧接着的一个十六进制数0x0021,即十进制的33,这就代表z这个class文件的常量池中有32项常量,索引值为1~32。然后就是第一个常量了,上面说过,每种类型的常量开始的第一位都是一个u1类型的标志位,代表该常量的类型,这里是0x0a,十进制的10,查上面的表可知是CONSTANT_Methodref_info,说明这个常量是类中方法的符号应用。该类型常量的具体结构为:

image.gif编辑

第一个index值为0x0004,即指向常量池中的第4个常量,第二个index是0x0019,即指向常量池中的第25个常量。在JDK的bin目录中,Oracle公司已经为我们准备好一个专门用于分析Class文件字节码的工具:javap。我们可以用javap -verbose命令查看class文件的字节码内容。

image.gif编辑

可以看到和我们分析的一致,该class文件中确实有32项常量,从#1到#32。

四、17种数据类型结构总表

image.gif编辑

image.gif编辑

image.gif编辑

参考资料:

    1. Class文件中的常量池详解(上)_xinjing_wangtao的博客-CSDN博客
    2. 深入理解Java虚拟机(第三版)-- Class类文件结构_吴声子夜歌的博客-CSDN博客
    相关文章
    |
    23天前
    |
    数据库 虚拟化 Windows
    虚拟机数据恢复—XenServer虚拟机磁盘文件丢失的数据恢复案例
    虚拟机数据恢复环境: 某品牌服务器通过同品牌某型号的RAID卡,将4块STAT硬盘为一组RAID10阵列。上层部署XenServer虚拟化平台,虚拟机安装Windows Server系统,每台虚拟机有两个虚拟机磁盘(系统盘 + 数据盘),虚拟机作为Web服务器使用。 虚拟机故障&分析: 机房异常断电导致服务器中一台VPS(XenServer虚拟机)不可用,虚拟磁盘文件丢失。
    |
    1月前
    |
    Java
    jvm复习,深入理解java虚拟机一:运行时数据区域
    这篇文章深入探讨了Java虚拟机的运行时数据区域,包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、元空间和运行时常量池,并讨论了它们的作用、特点以及与垃圾回收的关系。
    60 19
    jvm复习,深入理解java虚拟机一:运行时数据区域
    |
    15天前
    |
    存储 算法 Java
    Java虚拟机(JVM)的内存管理与性能优化
    本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
    |
    21天前
    |
    存储 运维 虚拟化
    虚拟化数据恢复——Hyper-V虚拟化故障导致虚拟机文件丢失的数据恢复案例
    在Windows Server上部署的Hyper-V虚拟化环境中,因存储中虚拟机数据文件丢失导致服务瘫痪。北亚企安数据恢复工程师通过物理检测、操作系统及文件系统检测,确定为人为格式化造成,并通过镜像硬盘、重组RAID、分析并恢复文件索引项等步骤,成功恢复数据,最终在新Hyper-V环境中验证并迁移所有虚拟机,确保用户业务恢复正常运行。
    |
    26天前
    |
    SQL 缓存 Java
    JVM知识体系学习三:class文件初始化过程、硬件层数据一致性(硬件层)、缓存行、指令乱序执行问题、如何保证不乱序(volatile等)
    这篇文章详细介绍了JVM中类文件的初始化过程、硬件层面的数据一致性问题、缓存行和伪共享、指令乱序执行问题,以及如何通过`volatile`关键字和`synchronized`关键字来保证数据的有序性和可见性。
    24 3
    |
    24天前
    |
    存储 算法 Java
    深入理解Java虚拟机(JVM)及其优化策略
    【10月更文挑战第10天】深入理解Java虚拟机(JVM)及其优化策略
    36 1
    |
    26天前
    |
    小程序 Oracle Java
    JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
    这篇文章是关于JVM基础知识的介绍,包括JVM的跨平台和跨语言特性、Class文件格式的详细解析,以及如何使用javap和jclasslib工具来分析Class文件。
    35 0
    JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
    |
    1月前
    |
    Linux 测试技术 虚拟化
    解决虚拟机文件因快照占用硬盘空间较多的情况(压缩虚拟机文件,节省硬盘空间)
    解决虚拟机文件因快照占用硬盘空间较多的情况(压缩虚拟机文件,节省硬盘空间)
    121 1
    |
    2天前
    |
    存储 SQL 数据库
    虚拟化数据恢复—Vmware虚拟机误还原快照的数据恢复案例
    虚拟化数据恢复环境: 一台虚拟机从物理机迁移到ESXI虚拟化平台,迁移完成后做了一个快照。虚拟机上运行了一个SQL Server数据库,记录了数年的数据。 ESXI虚拟化平台上有数十台虚拟机,EXSI虚拟化平台连接了一台EVA存储,所有的虚拟机都存放在EVA存储上。 虚拟化故障: 工组人员误操作将数年前迁移完成后做的快照还原了,也就意味着虚拟机状态还原到数年前,近几年数据都被删除了。 还原快照相当于删除数据,意味着部分存储空间会被释放。为了不让这部分释放的空间被重用,需要将连接到这台存储的所有虚拟机都关掉,需要将不能长时间宕机的虚拟机迁移到别的EXSI虚拟化平台上。
    68 50