Java虚拟机-字节码指令
字节码指令
Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)构成。Java虚拟机采用面向操作数栈而不是面向寄存器的架构,所以大多数指令都不包含操作数,只有一个操作码。
Java虚拟机操作码长度限制为一个字节(0-255),并且Class文件格式放弃类编译后代码的操作数长度对齐。所以虚拟机处理那些超过一个字节数据的时候,不得不在运行时从字节中重建出具体的数据的结构。这种操作会导致解释执行字节码时损失一些性能,但是这样意味着节省很多填充和间隔符号,编译代码也更加短小精干。这也是因为Java最初设计是面向网络、智能家电的技术背景,并且一直沿用至今。现在的网络带宽相比几十年前已经扩宽了很多倍,本地的计算性能也提高了无数倍。那现在这个思想是否还需要继续保持呢?在56k拨号上网、386的时代Java虚拟机针对编译时的优化或许决定了应用的成败,但是在现在5G和16甚至32核服务器以及Java虚拟机自身的发展与优化,常见的问题主要就是OOM了。
字节码与数据类型
Java虚拟机的指令集中,大多数指令都包含了其操作对应的数据类型,记得刚才说过操作码长度只有一个字节,意味着操作码总数不能超过256条。Java虚拟机支持的数据类型包含8种(byte,short,int,long,float,double,char,reference),大部分指令都不支持byte、short、和char,甚至没有任何指令支持boolean。编译期会在编译期或运行期将byte和short的数据带符号、boolean和char数据零位扩展为int类型。
指令中包含例如 const、load指令,针对int、long、float、double、reference分别为:iconst,lconst,fconst,dconst,aconst;iload、lload、fload、dload、aload。
加载和存储指令
load相关指令将一个局部变量加载到操作栈。
store相关指令将一个数值从操作数栈存储到局部变量表。
push、const相关指令将一个常量加载到操作数栈。
扩充局部变量表的访问索引的指令:wide。
运算指令
运算指令用于对两个操作数栈上的值进行某种特定运算,并把结果重新存入到操作栈顶,大体分为两种:整型数据运行指令与浮点型数据进行运算指令。
所有指令包括:加(add),减(sub),乘(mul),除(div),求余(rem),取反(neg),位移(shl,shr),按位或(or),按位与(and),按位异或(xor),局部变量自增(inc),比较(cmp)
类型转换指令
无需显式转换,宽化类型转换(小范围向大范围的安全转换):int到long、float、double;long到float、double;float到double;
需要显示转换,窄化类型转换:int到byte、char、short;long到int;float到int、long;double到int、long、float;
Java虚拟机规范中明确规定数值类型的窄化转换指令永远不可能导致虚拟机抛出运行时异常。
对象创建与访问指令
创建类实例的指令:new
访问类字段:getfield、putfield、getstatic、putstatic
检查类实例类型:instanceof、checkcast
创建数组:newarray、anewarray、multianewarray
加载数组元素到操作数栈:aload相关
将操作数栈的值存储到数组元素中的指令:astore
取数据长度:arraylength
操作数栈管理指令
将操作数栈顶一个或两个元素出栈:pop,pop2
复制栈顶元素的数值并且压入栈顶:dup、dup_x等相关
栈顶两个数值互换:swap
控制转移指令
控制转移指令可以让Java虚拟机有条件或者无条件从指定位置指令而不是下一条指令继续执行程序。从概念模型上理解,可以认为控制转移指令是在有条件或无条件的修改PC寄存器的值。
条件分支:if相关(ifeq、iflt、ifnotnull等)
复合条件分支:switch(tableswitch,lookupswitch)
无条件分支:goto,jsr(goto、goto_w、jsr、jsr_w、ret)
由于各种数据类型的比较最终都会转换为int进行比较,所以int类型的条件分支指令时最为丰富和强大的。
方法调用和返回指令
invokevirtual用于调用对象的实例方法,最常见的用法。
invokeinterface用于调用接口方法。
invokespecial用于调用特殊处理的实例方法,如实例初始化方法、私有方法、父类方法。
invokestatic用于调用静态方法。
invokedynamic用于在运行时动态解析出调用点限定符所引用的方法,并执行该方法。
方法调用指令与数据类型无关,返回指令与数据类型有关。
指令包括:ireturn(返回值时boolean、byte、char、short、int时使用)、lreturn、freturn、dreturn、areturn、return(返回值void,实例初始化方法、类和接口的类初始化方法使用)。
异常处理指令
异常抛出都有athrow指令实现。
处理异常(catch语句)不是有字节码指令来实现的(很久之前曾经使用jsr和ret指令,现在已经不用了),而是采用异常表来完成的。
同步指令
Java中的同步关键字为synchronized语句块,指令集中有monitorenter和monitorexit两条指令支持。
Java虚拟机-字节码指令的更多相关文章
- 【java虚拟机系列】从java虚拟机字节码执行引擎的执行过程来彻底理解java的多态性
我们知道面向对象语言的三大特点之一就是多态性,而java作为一种面向对象的语言,自然也满足多态性,我们也知道java中的多态包括重载与重写,我们也知道在C++中动态多态是通过虚函数来实现的,而虚函数是 ...
- java虚拟机字节码执行引擎
定义 java虚拟机字节码执行引擎是jvm最核心的组成部分之一,它做的事情很简单:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果.在不同的虚拟机实现里,执行引擎在执行java代码 ...
- Java虚拟机--字节码指令集
1. 字节码指令集简介: Java虚拟机的指令由一个字节长度的,代表着某种特定操作含义的操作码(Opcode)以及跟随其后的零至多个代表此操作所需参数的操作数(Operands)所构成.虚拟机中许多指 ...
- Java虚拟机-字节码执行引擎
概述 Java虚拟机规范中制定了虚拟机字节码执行引擎的概念模型,成为各种虚拟机执行引擎的统一外观(Facade).不同的虚拟机引擎会包含两种执行模式,解释执行和编译执行. 运行时帧栈结构 栈帧(Sta ...
- 虚拟机字节码指令表 JVM
虚拟机字节码指令表 标签(空格分隔): Java基础 JVM 记录虚拟机字节码指令,方便分析.以下内容来自<深入理解Java虚拟机> 字节码 助记符 指令含义 0x00 nop 什么都不做 ...
- 第32篇-解析interfacevirtual字节码指令
在前面介绍invokevirtual指令时,如果判断出ConstantPoolCacheEntry中的_indices字段的_f2属性的值为空,则认为调用的目标方法没有连接,也就是没有向Constan ...
- 第34篇-解析invokeinterface字节码指令
与invokevirtual指令类似,当没有对目标方法进行解析时,需要调用LinkResolver::resolve_invoke()函数进行解析,这个函数会调用其它一些函数完成方法的解析,如下图所示 ...
- [四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式
前言简介 前文已经对虚拟机进行过了简单的介绍,并且也对class文件结构,以及字节码指令进行了详尽的说明 想要了解JVM的运行机制,以及如何优化你的代码,你还需要了解一下,java编译器到底是 ...
- 深入理解java虚拟机(六)字节码指令简介
Java虚拟机指令是由(占用一个字节长度.代表某种特定操作含义的数字)操作码Opcode,以及跟随在其后的零至多个代表此操作所需参数的称为操作数 Operands 构成的.由于Java虚拟机是面向操作 ...
随机推荐
- 单元测试实践(SpringCloud+Junit5+Mockito+DataMocker)
网上看过一句话,单元测试就像早睡早起,每个人都说好,但是很少有人做到.从这么多年的项目经历亲身证明,是真的. 这次借着项目内实施单元测试的机会,记录实施的过程和一些总结经验. 项目情况 首先是背景,项 ...
- Python从入门到精通视频(全60集) ☝☝☝
Python从入门到精通视频(全60集) Python入门到精通 学习 教程 首先,课程的顺序需要调整:一和三主要是介绍学习和布置开发环境的,一介绍的是非VS开发,三介绍的是VS开发.VS2017现在 ...
- Salesforce学习之路-developer篇(四)Visualforce结合Reports展示图表
Salesforce作为一款CRM系统,个人觉得最重要的环境便是在于数据的展示和联动,而Salesforce也本身提供了相当强大的功能,Report在展示图表的方面十分强大,前段时间更是宣布以157亿 ...
- 虚拟机桥接模式下将虚拟IP设为静态IP
一:虚拟机设置桥接模式 1.进入虚拟机设置中将网络适配器设置成桥接模式,如下图 2.编辑--虚拟网络编辑器--选择桥接 3.如上图中桥接模式下的桥接到--将自动改成与本机匹配的虚拟网卡,本机虚拟网卡查 ...
- Ubuntu 16.04安装Java 8
1 Java 8 下载地址 http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-zhs. ...
- phpstorm 新加入项目的文件--全局搜索不到 ctrl + shift + R
通过文件名查找文件 ,能搜到其他的现有文件,只是新加入的文件,无法出现在搜索到的结果中 . 总不可能在搜索的关键词一直拼写错误吧 , 那能想到的只有缓存出问题了. 新加入的文件,新加入的文件.... ...
- NOIP2009 Hankson 的趣味题 : 数论
题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson.现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题. 今天在课堂上,老师讲解 ...
- Java中String类的特殊性
java中特殊的String类型 Java中String是一个特殊的包装类数据有两种创建形式: String s = "abc"; String s = new String(&q ...
- 从C++到C++/CLI
本文转载于:https://www.cnblogs.com/feisky/archive/2009/11/22/1607999.html 刘未鹏(pongba) /文 看起来只是在C++后面多写了一个 ...
- 【Java】遍历List/Set/Map集合的一些常用方法
/* * 遍历List/Set/Map集合的一些常用方法 */import java.util.ArrayList;import java.util.HashMap;import java.util. ...