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

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


相关推荐
敲代码娶不了六花21 分钟前
jsp | servlet | spring forEach读取不了对象List
java·spring·servlet·tomcat·list·jsp
Yhame.22 分钟前
深入理解 Java 中的 ArrayList 和 List:泛型与动态数组
java·开发语言
是小崔啊2 小时前
开源轮子 - EasyExcel02(深入实践)
java·开源·excel
myNameGL2 小时前
linux安装idea
java·ide·intellij-idea
青春男大2 小时前
java栈--数据结构
java·开发语言·数据结构·学习·eclipse
HaiFan.3 小时前
SpringBoot 事务
java·数据库·spring boot·sql·mysql
我要学编程(ಥ_ಥ)3 小时前
一文详解“二叉树中的深搜“在算法中的应用
java·数据结构·算法·leetcode·深度优先
music0ant3 小时前
Idea 添加tomcat 并发布到tomcat
java·tomcat·intellij-idea
计算机徐师兄4 小时前
Java基于SSM框架的无中介租房系统小程序【附源码、文档】
java·微信小程序·小程序·无中介租房系统小程序·java无中介租房系统小程序·无中介租房微信小程序
源码哥_博纳软云4 小时前
JAVA智慧养老养老护理帮忙代办陪诊陪护小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台