单纯的看 JVM 规范有点无聊了,看的云里雾里的,所谓“不闻不若闻之,闻之不若见之,见之不若知之,知之不若行之,学至于行而止矣,行之,明也”。本文从一个简单的Java程序一步一步探讨Class文件的结构。先从简单的 Hello World 开始,使用 javac 和 javap命令进行编译和反编译,由于反编译输出的信息太多,将分成片段来进行描述,如下:
其中 javac –g 表示生成所有的调试信息,javap –p –v 表示显示全部的详细信息。每个Class文件都是以 8-bit 为单位的字节流,多字节数据以 big-endian 大端排列(比如1314这个数,以 4字节存储,那么,大端表示为 0x00000522,小端表示为0x22050000)。为了标识class文件的正确性,每个class都有一个magic魔数(0xCAFEBABE),和两个主从版本号字段,如上图。JVM在加载链接时,会进行校验。使用高版本编译的文件,不能再低版本使用,反之可以。下面查看下class文件的十六进制表示:
从图中可以看出,前4个字节为magic=0xcafebabe,2字节的minor=0x0000,2字节的major=0x0034=3*16+4=52,在往后的 2 个字节 0x0022 表示常量池的大小为34,根据JVM规范里的Class文件格式,根据相应的偏移量,就可以解析你需要的信息。这里的字节序是网络序,比较符合我们的直觉。ClassFile 结构如下:
JVM 执行时,不依赖类,实例或接口在内存是怎么布局的,而是依赖运行时常量池,基于栈来执行指令。常量池中包含字面量和符号引用,字面量就是字符串常量和数值常量;符号引用就是用来描述类或接口、字段名和其描述符、方法名和其描述符。根据 ClassFile 的结构,可以看到 2 字节表示常量池大小,后面 cp_info 是具体内容,cp_info不同类型的大小不同,常量池中的类型如下:
海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com
原标题:JVM之Class文件
关键词:jvm