小师妹学JVM之:java的字节码byte code简介
简介
Byte Code也叫做字节码,是连接java源代码和JVM的桥梁,源代码编译成为字节码,而字节码又被加载进JVM中运行。字节码怎么生成,怎么查看字节码,隐藏在Byte Code背后的秘密是什么呢?快跟小师妹一起来看看吧。
Byte Code的作用
小师妹:F师兄,为什么Java需要字节码呢?直接编译成为机器码不是更快吗?
小师妹,Java的设计初衷是一次编写,到处运行。为了兼容各个平台的运行环境,java特别为各种平台设计了JVM。
我们可以把JVM看做是一种抽象,对外提供了统一的接口。这样我们只需要编写符合JVM规范的代码,即可在JVM中运行。
回想下之前我们提到过的java的执行过程:

- 编写java代码文件比如Example.java
- 使用java编译器javac将源文件编译成为Example.class文件
- JVM加载生成的字节码文件,将其转换成为机器可以识别的native machine code执行
小师妹:F师兄,我有一个大胆的想法,JVM的作用是将字节码解释或者编译成为机器码。然后在相应的运行环境中执行。那么有没有可能,不需要JVM,不需要机器码,而是直接在对应的平台上执行字节码呢?
爱因斯坦说过没有想像力的灵魂,就像没有望远镜的天文台。小师妹你这个想法很好,这种实现有个专业的说法叫做:Java processor。
Java processor就是用硬件来实现的JVM。因此字节码可以直接在Java processor中运行。
其中比较出名的是Jazelle DBX,这是一个主要支持J2ME环境的硬件架构。为了提升java在手机端的执行速度。
但是这样做其实也是有缺点的,后面我们会讲到,java字节码中的指令非常非常多。所以如果用硬件来实现的话,就会非常非常复杂。
一般来说Java processor不会实现全部的字节码中的功能,只会提供部分的实现。
查看Byte Code字节码
小师妹:F师兄,那使用javac编译过后的class文件跟字节码有什么关系呢?
class文件中大部分都是byte code,其他的部分是一些meta data元数据信息。这些组合在一起就是class文件了。
小师妹:F师兄,你说class文件是byte code,为什么我在IDE中打开的时候,直接显示的是反编译出来的源文件呢?
小师妹,这是IDE的一个便利功能。因为大多数情况下,没有人想去看class文件的Byte code的,大家都是想去看看这个class文件的源文件是什么样的。
我们举个最简单的例子:

这个类中,我们定义了一个很简单的testByteCode方法,里面定义了两个变量,然后返回他们两个的和。
现在有两种方法来查看这个类的Byte Code:
第一种方法是用javap命令:
javap -c ByteCodeUsage.class

生成的结果如上所示。
第二种方法就是在IDEA中,选中class文件,然后在view中选中show Bytecode:

我们看下输出结果:

两个的结果在显示上面可能有细微的差异,但是并不影响我们后面对其的解析。
java Byte Code是怎么工作的
小师妹:F师兄,能讲解一下这些byte code到底是怎么工作的吗?
首先我们要介绍一下JVM的实现是基于栈的结构的。为什么要基于栈的结构呢?那是因为栈是最适合用来实现function互相调用的。
我们再回顾一下上面的testByteCode的字节码。里面有很多iconst,istore的东西,这些东西被称作Opcode,也就是一些基于栈的操作指令。
上面讲了java bytecode的操作指令其实有很多个。下面我们列出这些指令的部分介绍:

实在是太多了,这里就不把所有的列出来了。
我们看到的指令名字其实是一个助记词,真实的Opcode是一个占用两个字节的数字。
下面我们来详细解释一下testByteCode方法:
public int testByteCode();
Code:
0: iconst_1
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: ireturn
第一步,iconst_1将int 1加载到stack中。
第二步,istore_1将入栈的int 1出栈,并存储到变量1中。
第三步,iconst_2将int 2入栈。
第四步,istore_2将入栈的int 2出栈,并存储到变量2中。
第五步,iload_1将变量1中的值入栈。
第六步,iload_2将变量2中的值入栈。
第七步,iadd将栈中的两个变量出栈,并相加。然后将结果入栈。
第八步,ireturn将栈中的结果出栈。
这几步实际上完美的还原了我们在testByteCode方法中定义的功能。
当然我们只介绍了最贱的byte code命令,通过这些简单的命令可以组合成为更加复杂的java命令。
总结
本文介绍了java byte code的作用和具体的指令,并分析了一个简单的例子来做说明。希望大家能够掌握。
本文的例子https://github.com/ddean2009/learn-java-base-9-to-20
本文作者:flydean程序那些事
本文链接:http://www.flydean.com/jvm-byte-code/
本文来源:flydean的博客
欢迎关注我的公众号:程序那些事,更多精彩等着您!
小师妹学JVM之:java的字节码byte code简介的更多相关文章
- 小师妹学JVM之:JVM的架构和执行过程
目录 简介 JVM是一种标准 java程序的执行顺序 JVM的架构 类加载系统 运行时数据区域 执行引擎 总结 简介 JVM也叫Java Virtual Machine,它是java程序运行的基础,负 ...
- 小师妹学JVM之:JIT中的PrintAssembly
目录 简介 使用PrintAssembly 输出过滤 总结 简介 想不想了解JVM最最底层的运行机制?想不想从本质上理解java代码的执行过程?想不想对你的代码进行进一步的优化和性能提升? 如果你的回 ...
- 小师妹学JVM之:深入理解JIT和编译优化-你看不懂系列
目录 简介 JIT编译器 Tiered Compilation分层编译 OSR(On-Stack Replacement) Deoptimization 常见的编译优化举例 Inlining内联 Br ...
- 小师妹学JVM之:JDK14中JVM的性能优化
目录 简介 String压缩 分层编译(Tiered Compilation) Code Cache分层 新的JIT编译器Graal 前置编译 压缩对象指针 Zero-Based 压缩指针 Escap ...
- 小师妹学JVM之:JIT中的LogCompilation
目录 简介 LogCompilation简介 LogCompilation的使用 解析LogCompilation文件 总结 简介 我们知道在JVM中为了加快编译速度,引入了JIT即时编译的功能.那么 ...
- 小师妹学JVM之:JIT中的PrintCompilation
目录 简介 PrintCompilation 分析PrintCompilation的结果 总结 简介 上篇文章我们讲到了JIT中的LogCompilation,将编译的日志都收集起来,存到日志文件里面 ...
- 小师妹学JVM之:JVM中的Safepoints
目录 简介 GC的垃圾回收器 分代回收器中的问题 safepoints safepoint一般用在什么地方 总结 简介 java程序员都听说过GC,大家也都知道GC的目的是扫描堆空间,然后将那些标记为 ...
- 小师妹学JVM之:GC的垃圾回收算法
目录 简介 对象的生命周期 垃圾回收算法 Mark and sweep Concurrent mark sweep (CMS) Serial garbage collection Parallel g ...
- 小师妹学JVM之:逃逸分析和TLAB
目录 简介 逃逸分析和栈上分配 TLAB简介 TLAB详解 设置TLAB空间的大小 TLAB中大对象的分配 TLAB空间中的浪费 总结 简介 逃逸分析我们在JDK14中JVM的性能优化一文中已经讲过了 ...
随机推荐
- CSS用户自定义样式
在浏览器中打开前面写的例子页面,你会发现 <strong> 元素中的文字会比其他文字粗一些.这些样式就是在浏览器定义的默认HTML样式. 而<strong> 元素是红色的,这是 ...
- 运用惰性删除和定时删除实现可过期的localStorage缓存
localStorage简介 使用localStorage可以在浏览器中存储键值对的数据.经常被和localStorage一并提及的是sessionStorage,它们都可以在当浏览器中存储键值对的数 ...
- Rocket - tilelink - AsyncCrossing
https://mp.weixin.qq.com/s/v8plWCBD8vZkxykjJe4TCg 介绍AsyncCrossing的实现,主要介绍如何实现diplomacy Node和LazyMo ...
- Rocket - config - DefaultConfig
https://mp.weixin.qq.com/s/zWW00D0fb8h7_TotGD9YoQ 介绍DefaultConfig类的组成. 1. DefaultConfig Defa ...
- 万字超强图文讲解AQS以及ReentrantLock应用(建议收藏)
| 好看请赞,养成习惯 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it ...
- Java实现 蓝桥杯 算法训练 乘法次数
乘法次数 资源限制 时间限制:1.0s 内存限制:999.4MB 问题描述 给你一个非零整数,让你求这个数的n次方,每次相乘的结果可以在后面使用,求至少需要多少次乘.如24:22=22(第一次乘),2 ...
- 用mvc框架查询数据库数据
介绍下mvc框架,mvc框架一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑. 首先我们 ...
- zabbix 监控cpu 温度
Zabbix监控Linux主机CPU温度 一.客户端 1.客户Linux主机安装Im_sensors [root@localhost ~]# yum install -y lm-sensors-y ...
- 快速升级Zabbix 5.0 版本
Zabbix 5.0 增加了很多新功能,如:垂直菜单.隐藏菜单.用户界面中的测试项目.限制代理检查.查找并替换预处理步骤 ES7支持等等...快来部署体验一把尝鲜体验 Zabbix 5.0 吧 ...
- Uber基于Apache Hudi构建PB级数据湖实践
1. 引言 从确保准确预计到达时间到预测最佳交通路线,在Uber平台上提供安全.无缝的运输和交付体验需要可靠.高性能的大规模数据存储和分析.2016年,Uber开发了增量处理框架Apache Hudi ...