JVM(四):深入分析Java字节码-下
JVM(四):深入分析Java字节码-下
在上文中,我们讲解了 Class 文件中的文件标识,常量池等内容。在本文中,我们就详细说一下剩下的指令集内容,阐述其分别代表了什么含义,以及 JVM 团队这样设计的意义。
简介
JVM 指令设计为仅有一个字节长度,由操作码和紧随其后的零至多个操作数来构成。
这里说到 JVM 的指令仅有一个字节,这意味着 JVM 在操作超过一个字节长度的数据时,需要在运行时重建出多字节数据类型的具体数据结构,例如 Long 等。这会导致这个操作不是原子操作,在高并发的情况下,就有可能会导致错误。
由于 JVM 的操作码长度只有一个字节,因此设计指令的时候,需要考虑所有指令加起来不能超过一个字节长度,正因如此,有许多数据类型是没有其对应的操作码的,其操作的方式是将其数据类型进行向上转型为其他的数据类型来参与运算。
例如大多数对于 boolean、byte、short 和 char 类型数据的操作,实际上是将其转换成 int 类型来处理的。
指令详解
JVM 指令如果详细来说的话有一百多个,在这里全部展开来描述的,不免有流水账的嫌疑,且价值不大,因此在本文中仅粗略描述一下,并找了一些关键的指令对其进行详细拆解,如果读者对其他指令有兴趣的话可以自行 Google 或翻书学习。
全部指令的内容
加载和存储指令:用于将数据在栈帧中的局部变量表和操作数栈之间转移(栈帧的布局放在以后的文章 JVM-内存布局中进行介绍,在这里读者只要明白其是根据栈进行操作就可以了)。eg:load,store;
运算指令:对两个操作数栈上的值进行计算并重新存入到操作栈顶。eg:add,sub,mul,div,rem,neg,shr,or,and,inc……;
类型转换指令:将一个值数据类型进行转换为其他的类型。eg:x2x;
对象创建与访问指令:new,newarray(数组和类实例创建和操作是不同的);
操作数栈操作指令:直接操作操作数栈。eg:pop,swap;
控制转移指令:有条件或无条件的控制 JVM 从指定的位置执行程序。(可以简单理解为修改程序计数器中的值)。eg:if,goto……;
方法调用和返回指令:根据对象的实际类型进行虚方法分配,调用类方法,调用接口方法等。另外还有根据不同的返回类型的不同返回指令;
异常处理指令:目前异常处理在 JVM 内部是通过异常表来完成的;
Exception table:
from to target type
0 8 14 Class java/lang/RuntimeException
0 8 29 any
14 23 29 any
from 行 到 to 行之间的字节码指令如果出现了 type 以及其子类的类型错误,就跳转到 target 行对应的字节码指令进行执行;
- 同步指令:同步指令是通过管程(Monitor)来实现的。
- 同步方法内部分为方法级的同步和方法内部一段指令的同步。
- 方法内部的指令,其实现逻辑是设置方法的访问标志:ACC_SYNCHRONIZED,如果其被设置了,表明该同步方法已经被别人调用,其他对象无法获得管程,就需要等待,在获得管程后才能继续执行。
- 指令内部的同步,其实现逻辑是通过字节码指令来控制的,字节码执行到需要同步的指令时,其会调用monitorenter 指令进行同步,此时其他线程无法进入这段指令序列,当程序正常或异常退出后,调用monitorexit 指令进行锁释放,此时其他线程就可以执行同步方法了。
PS:上面这段是 synchronized 关键字的本质含义,其具体的细节放到高并发编程系列文章中详细来说。
总结
通过 Class 文件这个中间文件,JVM 达成了语言无关性和平台无关性两个大突破,使得 Java 语言不仅达到了“一次编写,处处运行”,也使得其他语言只要符合 JVM 规范,就可以像 Java 一样,达到超然物外的无关性。

文章在公众号 “iceWang" 第一手更新,有兴趣的朋友可以关注公众号,第一时间看到笔者分享的各项知识点,谢谢!笔芯!
本系列文章主要借鉴自《深入分析 JavaWeb 技术内幕》和《深入理解 Java 虚拟机- JVM 高级特性与最佳实践》。
JVM(四):深入分析Java字节码-下的更多相关文章
- JVM(三):深入分析Java字节码-上
JVM(三):深入分析Java字节码-上 字节码文章分为上下两篇,上篇也就是本文主要讲述class文件存在的意义,以及其带来的益处.并分析其内在构成之一 ---字节码,而下篇则从指令集方面着手,讲解指 ...
- JVM 内部原理(六)— Java 字节码基础之一
JVM 内部原理(六)- Java 字节码基础之一 介绍 版本:Java SE 7 为什么需要了解 Java 字节码? 无论你是一名 Java 开发者.架构师.CxO 还是智能手机的普通用户,Java ...
- JVM 字节码指令手册 - 查看 Java 字节码
JVM 字节码指令手册 - 查看 Java 字节码 jdk 进行的编译生成的 .class 是 16 进制数据文件,不利于学习分析.通过下命令 javap -c Demo.class > Dem ...
- JVM 内部原理(七)— Java 字节码基础之二
JVM 内部原理(七)- Java 字节码基础之二 介绍 版本:Java SE 7 为什么需要了解 Java 字节码? 无论你是一名 Java 开发者.架构师.CxO 还是智能手机的普通用户,Java ...
- 深入了解java虚拟机(JVM) 第十章 字节码指令
一.字节码指令的含义 Java字节码指令由一个字节长度的,代表某种特定操作含义的数字(操作码)以及其后的零至多个代表此操作所需参数(操作数).此外字节码指令是面向操作数栈的,这里操作数栈在功能上对应实 ...
- 【JVM源码解析】模板解释器解释执行Java字节码指令(上)
本文由HeapDump性能社区首席讲师鸠摩(马智)授权整理发布 第17章-x86-64寄存器 不同的CPU都能够解释的机器语言的体系称为指令集架构(ISA,Instruction Set Archit ...
- JVM Java字节码的角度分析switch的实现
目录 Java字节码的角度分析switch的实现 引子 前置知识 一个妥协而又枯燥的方案 switch的实现 回顾历史 字节码分析 其他实现方式? Java字节码的角度分析switch的实现 作者 k ...
- JAVA字节码解析
Java字节码指令 Java 字节码指令及javap 使用说明 ### java字节码指令列表 字节码 助记符 指令含义 0x00 nop 什么都不做 0x01 aconst_null 将null推送 ...
- Java字节码操纵框架ASM小试
本文主要内容: ASM是什么 JVM指令 Java字节码文件 ASM编程模型 ASM示例 参考资料汇总 JVM详细指令 ASM是什么 ASM是一个Java字节码操纵框架,它能被用来动态生成类或者增强既 ...
随机推荐
- 原生开发之css样式问题(持续更新)
·移动端开发将div高度设置为设备高度 div{ Height:100vh; } · select选择器文字设置: /*select文字右对齐*/ select{ direction: rtl; } ...
- 详解Android Activity启动模式
相关的基本概念: 1.任务栈(Task) 若干个Activity的集合的栈表示一个Task. 栈不仅仅只包含自身程序的Activity,它也可以跨应用包含其他应用的Activity,这样有利于 ...
- WebSocket 的一些简单页面推送使用
因为做通信项目的时候,需要实时获取每个分机的当前状态,发现websocket还不错,只是对浏览器的要求比较高, 针对特定用户推送消息,网上有一些 public class GetHttpSession ...
- vb,wps,excel 提取括号的数字
Sub 抽离数字() Dim hang Range("h1").Select Columns("E:F").Select Selection.Clear Ran ...
- 本地连接批处理修改IP
例子: 本地连接修改IP netsh interface ip delete dns "本地连接" addr=allnetsh interface ip add dns " ...
- Python 保留n位小数
输出a, b 且保留三位小数 a = 2.3456 b = 2.0000 三种方法: round(a, 3)('%.3f' % a)Decimal(a).quantize(Decimal('0.000 ...
- mysql中 for update 使用
解释: for update是在数据库中上锁用的,可以为数据库中的行上一个排它锁.当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新.例子: 比如一张表三个字段 , id(商品id), n ...
- 16.04 下 ufw 防火墙的的开启、禁用、开放端口、关闭端口
16.04 下的 ufw 防火墙相关操作使用ufw命令.通过ufw --help可以查看所有相关命令. 打开防火墙 sudo ufw enable 重启防火墙 sudo ufw reload 打开指定 ...
- mysql图形化工具获取表的源码
打开数据库,选择要查看的表,点击右键>对象信息>DDL:
- python selenium定位总结(转)
转自:http://www.cnblogs.com/yufeihlf/p/5717291.html 父子定位元素 查找有父亲元素的标签名为span,它的所有标签名叫input的子元素 find_ele ...