一文讲清楚JVM字节码文件的组成

01-以正确的姿势打开文件

字节码文件中保存了 源代码编译之后的内容,以 二进制的方式 存储,无法直接用记事本打开阅读

通过NotePad++使用十六进制插件查看class文件:

推荐使用 jclasslib 工具查看字节码文件;
Github地址: https://github.com/ingokegel/jclasslib

02-字节码文件的组成

字节码文件总共可以分为以下几个部分:

  • 基础信息 :魔数、字节码文件对应的 Java版本号、访问标识(public final 等)、父类和接口信息
  • 常量池: 保存了 字符串常量、类或接口名、字段名,主要在字节码指令中使用
  • 字段: 当前类或接口声明的 字段信息
  • 方法: 当前类或接口声明的方法信息,核心内容为方法的字节码指令
  • 属性: 类的属性,比如源码的文件名、内部类的列表等

2.1 基本信息

基本信息包含了jclasslib中能看到的两块内容:一般信息 和 接口

01-魔数

02-主副版本号

03-其它基础信息

2.2 常量池

字节码文件中常量池的作用:避免相同的内容重复定义,节省空间

本质是一个数组

2.3 方法

通过分析方法的字节码指令,可以清楚地了解一个方法到底是如何执行的。先来看如下案例:

java 复制代码
int i = 0;
int j = i + 1;

这段代码编译成字节码指令之后是如下内容:

关于三条字节码指令的说明:

  • iconst_常量值:将 该常量放入操作数栈 中;
  • istore_数组下标:将 操作数栈中的值 放到 局部变量表对应的数组下标 中;
  • iload_数组下标:将 局部变量表中对应数组下标的值取出来放到操作数栈 中

01-操作数栈 & 局部变量表

要理解这段字节码指令是如何执行的,我们需要先理解两块内存区域:操作数栈和局部变量表。

  • 操作数栈 是用来存放临时数据的内容,是一个栈式的结构,先进后出;
  • 局部变量表 是存放方法中的局部变量,包含方法的参数、方法中定义的局部变量,在编译期就已经可以确定方法有多少个局部变量

02- i = i++ 的执行流程

i++ 的字节码指令如下:

  • 其中 iinc 1 by 1 指令指的是 将局部变量表1号位置增加1,其实就实现了i++的操作

最终结果仍为 0

03- i = ++i 的执行流程

而 ++i 只是对两个字节码指令的顺序进行了更改:iioad_1 和 iinc 1 by 1

最终结果为 1

04-经典面试题

05-思考

i++:iinc 1 by 1;
k+=1:iinc 2 by 1

i++ 和 k+=1 都是一行 iinc _ by 1 就搞定了,但是 j = j + 1 需要四行指令

相关推荐
汤姆yu13 分钟前
基于springboot+vue的企业OA办公系统
java·spring boot·后端·oa办公
南归北隐18 分钟前
Spring AI Alibaba Graph框架实现RAG私有知识库问答
java·后端·spring·spring ai·java rag实现
从琳开始98932 分钟前
[JavaEE]多线程初阶(下篇)------多线程案例(单例模式,阻塞队列,线程池,定时器)
java·单例模式·java-ee
乌暮36 分钟前
# Spring 入门与 Spring MVC 实战指南:从零理解 IoC 到 RESTful 图书管理
java·开发语言·后端·学习·spring·mvc·restful
java1234_小锋37 分钟前
Spring Boot 4.0 官宣:弃用 Undertow
java·spring boot·后端
jyOverQ40 分钟前
Redis 主从复制、Sentinel 和 Cluster 到底有什么区别?
java·redis·sentinel
青春逝如流水1 小时前
Java 线程在内存模型(JMM)与 JVM 实现:规范与落地的多元路径
java·开发语言·jvm·多线程·ai文章
wangbing11253 小时前
springboot应用关闭时触发动作
java·spring boot·后端
weixin_460443566 小时前
2026年新修订《网络安全法》实施:Java私有化考试系统如何做好SBOM、漏洞治理与安全升级?
java·开发语言·在线考试系统·企业培训考试系统·宏远培训考试系统·国企培训考试系统·国产化培训系统
海鸥-w9 小时前
什么是AOP
java