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

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


相关推荐
骑鱼过海的猫1231 分钟前
【java】java通过s3访问ceph报错
java·ceph·iphone
杨充7 分钟前
13.观察者模式设计思想
java·redis·观察者模式
Lizhihao_10 分钟前
JAVA-队列
java·开发语言
喵叔哟19 分钟前
重构代码之移动字段
java·数据库·重构
喵叔哟19 分钟前
重构代码之取消临时字段
java·前端·重构
fa_lsyk21 分钟前
maven环境搭建
java·maven
Daniel 大东41 分钟前
idea 解决缓存损坏问题
java·缓存·intellij-idea
wind瑞1 小时前
IntelliJ IDEA插件开发-代码补全插件入门开发
java·ide·intellij-idea
HappyAcmen1 小时前
IDEA部署AI代写插件
java·人工智能·intellij-idea
马剑威(威哥爱编程)1 小时前
读写锁分离设计模式详解
java·设计模式·java-ee