【JVM】JVM解析字节码文件过程(二)

JVM解析字节码文件过程

字节码中的数据结构

field_info

在Java字节码中,field_info结构是用来描述类或接口中的字段(成员变量的)。每个field_info结构对应类文件中的一个字段。其中它的组成部分包括如下:

1.access_flags:访问标志,表示字段的访问级别(如public, private, protected, static等)和其他属性(如final volatile等)

2.name_index:字段名的索引,它是一个指向常量池的索引,常量池中的对应条目包含字段的名称

3.descriptor_index:字段描述符的索引,它也是指向常量池的索引,描述符用来表示字段的类型(如int,float, java.lang.String等)

4.attribute_count:属性数量,表示接下来跟随的属性表中的属性数量。

5.attributes:属性表,包含了对字段的额外描述信息,如常量值(ConstantValue)、字段签名(Signature)、Synthetic标记等。

例如,有这样一个类文件,代码如下:

java 复制代码
public class MyClass {
      private int myField;
}

对应的field_info结构将包含如下信息:

  • 1.access_flags:表示private访问权限
  • 2.name_index:指向常量池中包含myField字符串的条目
  • 3.descritptor_index:指向常量池中包含"I"(表示Int类型)的条目
  • 4.attributes_count:通常为0,除非字段有额外的属性,如ConstantValue

method_info、Code_attribute

在Java字节码中,method_info结构用于描述类或接口中的方法。每个method_info结构对应类文件中的一个方法。以下是method_info结构的组成部分:

  • 1.acess_flags:访问标志,表示方法的访问级别(如public,private,protected, static等)和其他属性(如abstract. final,synchronized,native,strictfp等)
  • 2.name_index:方法名的索引,这是一个指向常量池的索引,常量池中的对应条目包含方法的蒙城
  • 3.descriptor_index:方法描述符的索引,这也是一个指向常量池中的索引,描述符用来表示方法的参数类型、返回值类型以及可能抛出的异常类型
  • 4.attributes_count:属性数量,表示接下来跟随的属性表中的属性数量
  • 5.attributes:属性表,包含了对方法的额外描述信息,如方法的代码(Code)、异常表(Exceptions)、方法签名(Signature)、注解(Annotation)等
    例如,有这样一个类文件,代码如下:
java 复制代码
public class MyClass {
    public void myMethod(int param) {
       // Method body ...
     }
}

对应的method_info结构将包含以下信息:

  • 1.access_flags:表示public访问权限
  • 2.name_index:指向常量池中包含myMethod字符串的条目
  • 3.descriptor_index:指向常量池中包含(I)V(表示一个int参数且没有返回值)的条目
  • 4.attributes_count:通常至少为1,因为大多数方法都会有一个Code属性,它包含方法的字节码指令

Code属性是method_info结构中最常见的属性,它包含以下字段:

  • 1.max_stack:操作数栈的最大深度
  • 2.max_locals:局部变量表所需的存储空间,单位是槽位(slot),每个槽位可以存储一个32位的数据类型
  • 3.code_length:字节码指令的数量
  • 4.code:实际的方法字节码指令序列
  • 5.exception_table_length:异常表中的条目数量
  • 6.exception_table:异常处理的信息
  • 7.exception_table:异常处理的信息
  • 8.attributes_count:Code属性中的属性数量
  • 9.attributes:Code属性中的属性表

LineNumberTable和Code结构之间的关系是什么?

LineNumberTable是Code属性中的一个可选属性,它提供了源代码行号与字节码指令之间的映射关系。这样,当异常被抛出或者在调试程序时,可以更准确地定位到源代码中的具体行。

  • 1.Code属性时method_info结构中的一个属性,它包含了方法的实际字节码指令、局部变量表大小、操作数栈大小等信息
  • 2.LineNumberTable属性:是Code属性中的一个可选属性,它位于Code属性的attributes数组中,如果存在,它允许调试器和其他工具将执行的字节码指令与源代码中的行号关联起来

LocalVariableTable是Code属性中的一个可选属性,它提供了方法执行期间局部变量与局部变量表槽位之间的关系。这个映射允许调试器和其他工具在运行时查看和修改变量的值,并且可以用于在异常堆栈跟踪中显示变量名

  • 1.Code属性:code属性包含方法的字节码指令、局部变量表大小、操作数栈等信息。它还包含一个属性表attributes,可以包含多个属性,比如LineNumberTalbe、LocalVariableTable等
  • 2.LocalVariableTable属性:LocalVariableTable是Code属性中的一个属性,位于attributes数组中。如果存在,它描述了方法中的每个局部变量及其在局部变量表中的位置、生命周期和类型
  • 3.LocalVariableTable中的每个条目都描述了一个局部变量,包括它的名字、类型、在局部变量表中的槽位索引以及它在字节码中的上明周期(开始和结束的偏移量)
  • 4.LocalVariableTable提供了调试器在执行期间识别和访问局部变量的能力,这对于断点调试和异常堆栈跟踪非常有用
  • 5.在编译时,编译器可以选择生成或不生成LocalVariableTable。如果生成了这个表,它会使得调试更加方便,但如果为了减小类文件大小或出于其他原因,这个表可能会被忽略
相关推荐
程序猿大帅2 小时前
别再只当调包侠了:用 Spring AI 落地 Function Calling,我被大模型硬生生砸出了三个大坑
java
程序员晓琪3 小时前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端
Flittly3 小时前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring
众少成多积小致巨4 小时前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
东坡白菜4 小时前
破局全栈:前端开发的Java入门实战记录—JPA(2)
java·后端
SimonKing10 小时前
艹,维护AI写的代码,我心态崩了......
java·后端·程序员
用户2986985301411 小时前
Java Word 文档样式进阶:段落与文本背景色设置完全指南
java·后端
小bo波1 天前
从"任意文件复制"深挖Java I/O:字符流与字节流的本质抉择
java·nio·io流·后端开发·文件复制
nanxun8862 天前
记一次诡异的 Docker 容器"串包"故障排查
java
用户1563068103512 天前
Day01 | Java 基础(Java SE)
java