一文讲清楚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 需要四行指令

相关推荐
深念Y1 小时前
IDEA下载JDK慢的真相:权限、DNS与CDN的解析
java·ide·intellij-idea
Remember_9931 小时前
【数据结构】二叉树:从基础到应用全面解析
java·数据结构·b树·算法·leetcode·链表
冷冷的菜哥1 小时前
springboot调用ffmpeg实现对视频的截图,截取与水印
java·spring boot·ffmpeg·音视频·水印·截图·截取
C++chaofan2 小时前
JUC并发编程:LockSupport.park() 与 unpark() 深度解析
java·开发语言·c++·性能优化·高并发·juc
人工智能AI技术2 小时前
Java程序员如何入门AI
java·人工智能
我是小疯子662 小时前
C++图论:从基础到实战应用
java·c++·图论
小码过河.2 小时前
设计模式——享元模式
java·设计模式·享元模式
J_liaty2 小时前
深入理解Java反射:原理、应用与最佳实践
java·开发语言·反射
小冷coding2 小时前
【面试】围绕‌服务注册与发现、配置中心、熔断限流、API网关路由‌四大核心组件会面临哪些问题?
java·面试·职场和发展