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

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


相关推荐
Dcs15 分钟前
VSCode等多款主流 IDE 爆出安全漏洞!插件“伪装认证”可执行恶意命令!
java
保持学习ing21 分钟前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
京东云开发者32 分钟前
Java的SPI机制详解
java
超级小忍1 小时前
服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
java·spring boot·后端
程序无bug1 小时前
Spring IoC注解式开发无敌详细(细节丰富)
java·后端
小莫分享1 小时前
Java Lombok 入门
java
程序无bug1 小时前
Spring 对于事务上的应用的详细说明
java·后端
食亨技术团队1 小时前
被忽略的 SAAS 生命线:操作日志有多重要
java·后端
苦学编程的谢1 小时前
Maven
java·maven·intellij-idea
考虑考虑1 小时前
Maven 依赖范围(Scope)
java·后端·maven