JVM字节码文件

文章目录

  • 字节码文件
    • [1. 基础信息](#1. 基础信息)
    • [2. 常量池](#2. 常量池)
    • [3. 方法](#3. 方法)

字节码文件

Java的字节码文件由基础信息、常量池、字段、方法、属性五个部分组成。

1. 基础信息

字节码中的基础信息包含魔术、字节码文件对应的Java版本号,以及访问标识(public final等等),父类和接口。

Magic魔术

  • 文件是无法通过文件拓展名来确定文件类型的,文件拓展名可以随意修改,不影响文件的内容
  • 软件通过文件的**头几个字节(文件头)**来校验文件的类型,如果软件不支持该种文件类型就会报错
  • Java字节码文件中,将文件头称为Magic魔术
  • 在Java字节码文件中的前4个字节为CAFEBABE

主副版本号

  • 主副版本号指的是编译字节码文件的JDK版本号,主版本号用来标识大版本号,JDK1.0-1.1使用了45.0-45.3,JDK1.2之后每升级一个大版本就加1,副版本号是当前主版本号相同时作为区分不同版本的标识,一般只需关心主版本号
  • 版本号的作用主要是判断当前字节码的版本和运行时的JDK是否兼容
  • JDK1.2之后版本号的计算方法就是主版本号-44,主版本号52就是JDK8

2. 常量池

常量池中保存了字符串常量、类或者接口名、字段名主要在字节码指令中使用。

  • 字节码文件中的常量池的作用就是为了避免相同的内容重复定义,节省空间
  • 常量池中的数据都有一个编号,编号从1开始,在字段或者字节码指令中通过编号可以快速的找到对应的数据
  • 字节码指令中通过编号引用到常量池的过程称为符号引用
  • 需要注意的是字段名也可能引用常量池中的字符串常量,比如说下面这段代码,字段名abc和其它3个字段的值abc都是引用了同一个字符串常量,进一步优化空间
java 复制代码
public class ConstantPoolTest2 {
    public static final String a1 = "abc";
    public static final String a2 = "abc";
    public static final String abc = "abc";
    public static void main(String[] args) {
        ConstantPoolTest2 constantPoolTest = new ConstantPoolTest2();
    }
}

3. 方法

当前类或者接口声明的方法信息(字节码指令)

字节码的方法中有这么几个部分:

  • 字节码指令
  • 操作数栈:临时存放数据的地方
  • 局部变量表数组:存放方法中局部变量的位置

有如下两行代码

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

编译后生成如下字节码指令

java 复制代码
iconst_0 // 将常量0放入操作数栈
istore_1 // 将操作数栈取出放入局部变量表数组1号位置
iload_1  // 将局部变量表数组1号位置的数据放入操作数栈中
iconst_1 // 将常量1 放入操作数栈
iadd     // 将操作数栈顶的两个数据相加,结果放入栈中
istore_2 // 将操作数栈顶的数据取出来放到局部变量数组2号位置
return // 方法结束返回

如下代码输出啥?

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

通过查看字节码的方法

java 复制代码
iconst_0 // 将0放入操作数栈
istore_1 // 从操作数栈取出栈顶元素取出放入局部变量表1号位置
iload_1 // 从局部变量表1号位置加载数据到操作数栈
iinc 1 by 1  // 在局部变量表1号位置数+1
istore_1 // 将操作数栈中的值保存到局部变量表中

i最后答案是0,我通过分析字节码指令发现,i++先把0取出来放入临时的操作数栈中接下来对i进行加1,i变成了1,最后再将之前保存的临时值0放入i,最后就变成了0。

一下这几种自增方式,谁的效率最高呢?

java 复制代码
i++
i += 1
i = i+1

直接来看对应的字节码

i++

java 复制代码
iconst_0
istore_1
iinc 1 by 1

i += 1

java 复制代码
iconst_0
istore_1
iinc 1 by 1

i = i + 1

java 复制代码
iconst_0
istore_1
iload_1
iconst_1
iadd
istore_1

理论来说字节码指令越少,效率是越高的


相关推荐
Ray Wang25 分钟前
3.JVM
jvm
极客先躯42 分钟前
高级java每日一道面试题-2024年10月3日-分布式篇-分布式系统中的容错策略都有哪些?
java·分布式·版本控制·共识算法·超时重试·心跳检测·容错策略
夜月行者1 小时前
如何使用ssm实现基于SSM的宠物服务平台的设计与实现+vue
java·后端·ssm
程序猿小D1 小时前
第二百六十七节 JPA教程 - JPA查询AND条件示例
java·开发语言·前端·数据库·windows·python·jpa
潘多编程1 小时前
Java中的状态机实现:使用Spring State Machine管理复杂状态流转
java·开发语言·spring
_阿伟_2 小时前
SpringMVC
java·spring
代码在改了2 小时前
springboot厨房达人美食分享平台(源码+文档+调试+答疑)
java·spring boot
猿java2 小时前
使用 Kafka面临的挑战
java·后端·kafka
wclass-zhengge2 小时前
数据结构篇(绪论)
java·数据结构·算法
何事驚慌2 小时前
2024/10/5 数据结构打卡
java·数据结构·算法