JVM-类文件结构

229 阅读4分钟

Java 虚拟机能够识别的是.class文件,而不管上层使用的是何种语言编写的代码,只要编译器能够编译成符合Java 虚拟机规范的.class 文件,JVM就可以对该文件加载运行。

Java虚拟机提供的语言无关性。Sun 公司最成功的产品不是Java,而是Java虚拟机,实现了跨平台运行的基石:一次编写,到处运行。 image.png

Class类文件的结构

Class文件是一组以8个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用8个字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8个字节进行存储。

下面就是通过命令 javac TestClass.java 以及 xxd TestClass.class TestClass.txt 命令将class 文件的字节码生成16进制的格式表现出来的。 image.png

这里我们先来弄清楚两个概念:无符号数

  • 无符号数:基本数据类型,以u1、u2、u4、u8 来分别代表1个字节、2个字节、4个字节、8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成的字符串值cafe babe 0000 003d 0016 0a00 0200 0307 以这段字节为例 | 无符号数类型 | 字节数 |示例 | --- | --- |--- | | u1 | 1个字节 | ca| | u2 | 2个字节 | feba| | u4 | 4个字节 | be 0000 00| | u8 | 8个字节 | 3d 0016 0a00 0200 03|

  • 表:多个无符号数或者其他表作为数据项构成的复合数据类型,所有的表名称后都加上了“_info”结尾。

类型名称数量描述
u4magic1class 文件的识别标志
u2minor_version1jdk的次版本号
u2major_version1jdk的主版本号
u2constant_pool_count1常量池中的常量个数(编号从1开始,21=22-1 个)
cp_infoconstant_poolconstant_pool_count-1常量池中的常量表
u2access_flags1访问标志
u2this_class1当前类
u2super_class1父类
u2interface_count1接口数量
u2interfacesinterface_count接口引用索引
u2fields_count1字段数量
field_infofieldsfields_count字段表
u2method_count1方法数量
method_infomethodmethod_count方法表
u2attributes_count1属性个数
attribute_infoattributesattributes_count属性表

无论是无符号数还是表,当需要描述同一类型但数量不定的多个数据时,经常会使用一个前置的容量计数器+若干个连续的数据项的形式------> “集合”

接下来,我们分析一下我们自己编写的代码 生成的每个字节码所代表的含义。

public class TestClass {
    private int m;

    public int inc() {
        return m + 1;
    }
}

通过javac TestClass.java 以及 xxd TestClass.class TestClass.txt 生成的字节码文件,然后我整理成了excel 文件。

image.png 上图中最主要的部分就是常量池部分,该份文件中所指的常量池有21项,常量池的索引从1开始的,所以22-1=21 项。和工具jclasslib 生成的一样

image.png

image.png

然后,我分析了一部分除常量池的一些其他属性,见图

image.png

后面没分析,太费时间了,只要对应着《深入理解Java 虚拟机》第六章中的描述,静下心来一步步分析,可以得出这张excel 中的所有字节都是能找到对应的描述关系的。这里我推荐几个参考资料的路径:

-《深入理解Java 虚拟机》第六章附录C 虚拟机字节码指令表

最后我附上一份我的分析草稿吧:

image.png

image.png

image.png

image.png

image.png

分析这玩意太费时了,本来想着在excel 中在做一次分析的,后来做着做着觉得这玩意单单靠自己看是不行的,一定要自己至少分一一遍,分析的时候,代码尽量写的简短,能够分析即可,不然,会让你分析到头大。分析了这个字节码文件,会对理解JVM有很大的帮助。对后面章节的学习很重要。