【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。如果生成了这个表,它会使得调试更加方便,但如果为了减小类文件大小或出于其他原因,这个表可能会被忽略
相关推荐
步行cgn2 小时前
Spring c 命名空间注入详解
java·后端·spring
明月_清风2 小时前
Maven 到底是什么?一篇文章搞懂 Java 项目构建与依赖管理
java·后端·maven
aramae3 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
Rain的Java大神之路3 小时前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
Wang's Blog4 小时前
Java 接入Redis: 通用命令与键管理
java·服务器·redis
Wang's Blog4 小时前
Java 接入Redis: 列表集合与有序集合操作命令
java·服务器·redis
Ivanqhz4 小时前
SVD++算法
java·服务器·网络·深度学习·神经网络
qq_2518364575 小时前
springboot vue3 开发实现 拼豆管理系统
java·开发语言·ai编程
caoerzhong5 小时前
JeeWMS 开源仓库管理系统全景解读:一套 Java WMS 如何把 WMS/OMS/BMS/TMS 装进同一个系统
java·开源
曹牧5 小时前
Java集合框架:List、ArrayList、Map 和 HashMap
java