JVM_3_类文件结构

概述

  1. 类文件结构
  2. 字节码指令
  3. 编译期处理
  4. 类加载阶段
  5. 类加载器
  6. 运行期优化

image-20210916170230617

类文件结构

一个简单的HelloWorld.java

package cn.chasing.jvm.t3
// HelloWorld示例
public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("hello world");
  }
}

执行

javac -parameters -d . HelloWorld.java

编译为HelloWorld.class后是这个样子,以八进制表示

image-20210916171510631

根据JVM规范,类文件结构如下

image-20210916171720756

魔数

0~3字节,表示它是否是【class】类型文件

image-20210916171831240

版本

4~7字节,表示类的版本00 32 (52) 表示是java8

image-20210916171939687

常量池

Constant TypeValue
CONSTANT_Class7
CONSTANT_Fieldref9
CONSTANT_Methodref10
CONSTANT_InterfaceMethodref11
CONSTANT_String8
CONSTANT_Integer3
CONSTANT_Float4
CONSTANT_Long5
CONSTANT_Double6
CONSTANT_NameAndType12
CONSTANT_Utf81
CONSTANT_MethodHandle15
CONSTANT_MethodType16
CONSTANT_InvokeDynamic18

8~9 字节,表示常量池长度,00 23 (35) 表示常量池有 #1~#34项,注意 #0 项不计入,也没有值

image-20210916173119340

第#1项 0a 表示一个 Method 信息,00 06 和 00 15(21) 表示它引用了常量池中 #6 和 #21 项来获得这个方法的【所属类】和【方法名】

image-20210916173148592

第#2项 09 表示一个 Field 信息,00 16(22)和 00 17(23) 表示它引用了常量池中 #22 和 # 23 项来获得这个成员变量的【所属类】和【成员变量名】

image-20210916173216154

第#3项 08 表示一个字符串常量名称,00 18(24)表示它引用了常量池中 #24 项

image-20210916173250860

第#4项 0a 表示一个 Method 信息,00 19(25) 和 00 1a(26) 表示它引用了常量池中 #25 和 #26项来获得这个方法的【所属类】和【方法名】

image-20210916173325154

第#5项 07 表示一个 Class 信息,00 1b(27) 表示它引用了常量池中 #27 项

image-20210916173345710

第#6项 07 表示一个 Class 信息,00 1c(28) 表示它引用了常量池中 #28 项

image-20210916173407099

第#7项 01 表示一个 utf8 串,00 06 表示长度,3c 69 6e 69 74 3e 是【 】,构造方法

image-20210916173432845

第#8项 01 表示一个 utf8 串,00 03 表示长度,28 29 56 是【()V】其实就是表示无参、无返回值

image-20210916173456434

第#9项 01 表示一个 utf8 串,00 04 表示长度,43 6f 64 65 是【Code】

image-20210916173517588

第#10项 01 表示一个 utf8 串,00 0f(15) 表示长度,4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65是【LineNumberTable】

image-20210916173538432

第#11项 01 表示一个 utf8 串,00 12(18) 表示长度,4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65是【LocalVariableTable】

image-20210916173603360

第#12项 01 表示一个 utf8 串,00 04 表示长度,74 68 69 73 是【this】

image-20210916173637222

第#13项 01 表示一个 utf8 串,00 1d(29) 表示长度,是【Lcn/itcast/jvm/t5/HelloWorld;】

image-20210916173711333

第#14项 01 表示一个 utf8 串,00 04 表示长度,74 68 69 73 是【main】

image-20210916173734208

第#15项 01 表示一个 utf8 串,00 16(22) 表示长度,是【([Ljava/lang/String;)V】其实就是参数为字符串数组,无返回值

image-20210916173807065

第#16项 01 表示一个 utf8 串,00 04 表示长度,是【args】

image-20210916173826344

第#17项 01 表示一个 utf8 串,00 13(19) 表示长度,是【[Ljava/lang/String;】

image-20210916173859368

第#18项 01 表示一个 utf8 串,00 10(16) 表示长度,是【MethodParameters】

image-20210916173938450

第#19项 01 表示一个 utf8 串,00 0a(10) 表示长度,是【SourceFile】

image-20210916173956339

第#20项 01 表示一个 utf8 串,00 0f(15) 表示长度,是【HelloWorld.java】

image-20210916174015532

第#21项 0c 表示一个 【名+类型】,00 07 00 08 引用了常量池中 #7 #8 两项

image-20210916174033651

第#22项 07 表示一个 Class 信息,00 1d(29) 引用了常量池中 #29 项

image-20210916174052536

第#23项 0c 表示一个 【名+类型】,00 1e(30) 00 1f (31)引用了常量池中 #30 #31 两项

image-20210916174115838

第#24项 01 表示一个 utf8 串,00 0f(15) 表示长度,是【hello world】

image-20210916174137320

第#25项 07 表示一个 Class 信息,00 20(32) 引用了常量池中 #32 项

image-20210916174155804

第#26项 0c 表示一个 【名+类型】,00 21(33) 00 22(34)引用了常量池中 #33 #34 两项

image-20210916174214126

第#27项 01 表示一个 utf8 串,00 1b(27) 表示长度,是【cn/itcast/jvm/t5/HelloWorld】

image-20210916174230106

第#28项 01 表示一个 utf8 串,00 10(16) 表示长度,是【java/lang/Object】

image-20210916174251996

第#29项 01 表示一个 utf8 串,00 10(16) 表示长度,是【java/lang/System】

image-20210916174308792

第#30项 01 表示一个 utf8 串,00 03 表示长度,是【out】

image-20210916174325894

第#31项 01 表示一个 utf8 串,00 15(21) 表示长度,是【Ljava/io/PrintStream;】

image-20210916174344994

第#32项 01 表示一个 utf8 串,00 13(19) 表示长度,是【java/io/PrintStream】

image-20210916174402268

第#33项 01 表示一个 utf8 串,00 07 表示长度,是【println】

image-20210916174422858

第#34项 01 表示一个 utf8 串,00 15(21) 表示长度,是【(Ljava/lang/String;)V】

image-20210916174443412

访问标识与继承信息

image-20210916190305559

image-20210916190329231

Field 信息

image-20210916190356535

image-20210916190409974

Method 信息

image-20210916190450989

一个方法由 访问修饰符,名称,参数描述,方法属性数量,方法属性组成

  • 红色代表访问修饰符(本类中是 public)

  • 蓝色代表引用了常量池 #07 项作为方法名称

  • 绿色代表引用了常量池 #08 项作为方法参数描述

  • 黄色代表方法属性数量,本方法是 1

  • 红色代表方法属性

    • 00 09 表示引用了常量池 #09 项,发现是【Code】属性

    • 00 00 00 2f 表示此属性的长度是 47

    • 00 01 表示【操作数栈】最大深度

    • 00 01 表示【局部变量表】最大槽(slot)数

    • 2a b7 00 01 b1 是字节码指令

    • 00 00 00 02 表示方法细节属性数量,本例是 2

    • 00 0a 表示引用了常量池 #10 项,发现是【LineNumberTable】属性

      • 00 00 00 06 表示此属性的总长度,本例是 6
      • 00 01 表示【LineNumberTable】长度
      • 00 00 表示【字节码】行号 00 04 表示【java 源码】行号
    • 00 0b 表示引用了常量池 #11 项,发现是【LocalVariableTable】属性

      • 00 00 00 0c 表示此属性的总长度,本例是 12
      • 00 01 表示【LocalVariableTable】长度
      • 00 00 表示局部变量生命周期开始,相对于字节码的偏移量
      • 00 05 表示局部变量覆盖的范围长度
      • 00 0c 表示局部变量名称,本例引用了常量池 #12 项,是【this】
      • 00 0d 表示局部变量的类型,本例引用了常量池 #13 项,是【Lcn/itcast/jvm/t5/HelloWorld;】
      • 00 00 表示局部变量占有的槽位(slot)编号,本例是 0

image-20210916190830059

  • 红色代表访问修饰符(本类中是 public static)

  • 蓝色代表引用了常量池 #14 项作为方法名称

  • 绿色代表引用了常量池 #15 项作为方法参数描述

  • 黄色代表方法属性数量,本方法是 2

  • 红色代表方法属性(属性1)

    • 00 09 表示引用了常量池 #09 项,发现是【Code】属性
    • 00 00 00 37 表示此属性的长度是 55
    • 00 02 表示【操作数栈】最大深度
    • 00 01 表示【局部变量表】最大槽(slot)数
    • 00 00 00 09 表示字节码长度,本例是 9
    • b2 00 02 12 03 b6 00 04 b1 是字节码指令
    • 00 00 00 02 表示方法细节属性数量,本例是 2
    • 00 0a 表示引用了常量池 #10 项,发现是【LineNumberTable】属性
      • 00 00 00 0a 表示此属性的总长度,本例是 10
      • 00 02 表示【LineNumberTable】长度
      • 00 00 表示【字节码】行号 00 06 表示【java 源码】行号
      • 00 08 表示【字节码】行号 00 07 表示【java 源码】行号
    • 00 0b 表示引用了常量池 #11 项,发现是【LocalVariableTable】属性
      • 00 00 00 0c 表示此属性的总长度,本例是 12
      • 00 01 表示【LocalVariableTable】长度
      • 00 10 表示局部变量名称,本例引用了常量池 #16 项,是【args】
      • 00 11 表示局部变量的类型,本例引用了常量池 #17 项,是【[Ljava/lang/String;】
      • 00 00 表示局部变量占有的槽位(slot)编号,本例是 0

image-20210916191101579

红色代表方法属性(属性2)

  • 00 12 表示引用了常量池 #18 项,发现是【MethodParameters】属性
    • 00 00 00 05 表示此属性的总长度,本例是 5
    • 01 参数数量
    • 00 10 表示引用了常量池 #16 项,是【args】
    • 00 00 访问修饰符

image-20210916191158906

附加属性

  • 00 01 表示附加属性数量
  • 00 13 表示引用了常量池 #19 项,即【SourceFile】
  • 00 00 00 02 表示此属性的长度
  • 00 14 表示引用了常量池 #20 项,即【HelloWorld.java】

image-20210916191237721

参考文献

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值