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虚拟机是面向操作 ...
随机推荐
- Python移动自动化测试面试 ☝☝☝
Python移动自动化测试面试 ☝☝☝ Python移动自动化测试面试 学习 教程 1.super 是干嘛用的?在 Python2 和 Python3 使用,有什么区别?为什么要使用 super? ...
- DataStructure之线性表以及其实现
线性表 应用:多项式的表示 什么是线性表 多项式表示问题给出的启示: 同一个问题可以有不同的表示(存储)方法 有一类共性问题 : 有序线性序列的租住和管理 “线性表(Linear List)” : 由 ...
- PMP 德尔菲技术
1.德尔菲技术,必须遵守以下几个规则: 每个专家只与主持人单线联系. 专家之间完全背靠背,更不能进行讨论.为保证专家提出独立见解,甚至需要把专家分散在不同的物理地点. 专家以匿名的书面形式提出意见. ...
- ThinkPhp3.1.3执行存储过程返回false
1.Tp在调用存储过程的时候,每次都显示false 返回一大片,下面是我自己的代码.
- 基于STL的堆略解
什么是STL 以下内容摘自这儿. STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.它是由Alexander Stepanov.Meng Le ...
- Mysql高手系列 - 第26篇:聊聊如何使用mysql实现分布式锁
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第26篇. 本篇我们使用my ...
- kmp算法,求重复字符串
public class Demo { public static void main(String[] args) { String s1 = "ADBCFHABESCACDABCDABC ...
- Java多线程编程(三)线程间通信
线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...
- 2017.12.21 学习vue的新得
温故而知新,这句话说的真的有道理.每次回顾vue总会学到不一样的知识点,我就在想,我第一遍到底看了什么? 废话不多说,简要记录今天的所得: 1.v-if 与 v-show 同:都是条件渲染 异:渲染的 ...
- nginx基于uwsgi部署Django
1.安装nginx yum install -y nginx(需要epel源) 2.安装uwsgi yum groupinstall "Development tools" yum ...