虚拟机字节码执行引擎】



JVM——虚拟机字节码执行引擎

JavaJava代码的时候可能会有解释执行(通过解释器执行)和编译执行(通过即时编译器产生本地代码执行)两种选择,也可能两者兼备,甚至还可能会包含几个不同级别的编译器执行引擎。

运行时栈帧结构

Virtual Machine Stack )的栈元素。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。

在编译程序代码的时候,栈帧中需要多大的局部变量表,多深的操作数栈都已经完全确定了,并且写入到方法表的Code而仅仅取决于具体的虚拟机实现。

。执行引擎运行的所有字节码指令都只针对当前栈帧进行操作。

栈帧的概念模型如下图所示:

局部变量表

是一组变量值存储空间.用于存放方法参数和方法内部定义的局部变量。在Java程序编译为Class文件时,就在方法的Code

Slot)为最小单位,虚拟机规范中并没有明确指明一个Slot应占用的内存空间大小。

Slot

如果执行的是实例方法(非staticSlotl

类变量有两次赋初始值的过程,初始值。

操作数栈

操作数栈的最大深度在编译的时候写入到code属性的max_stacks数据项中。操作数栈的每一个元素可以是任意的Java数据类型,包括longmax_stacks数据项中设定的最大值。

概念模型中,两个栈帧作为虚拟机栈的元素是完全相互独立的。但在大多虚拟机的实现里都会做一些优化处理,令两个栈帧出现一部分重叠。这样在进行方法调用的时候可以共用一部分数据无须进行额外的参数复制传递。

动态链接

方法返回地址

另外一种退出方式是,在方法执行过程中遇到了异常,并且这个异常没有在方法体内得到处理,无论是Java虚拟机内部产生的异常,还是代码中使用athrow

方法调用

解析

Resolution)。

在Java语言中,符合“编译期可知,运行期不可变”这个要求的方法,主要有静态方法和私有方法两大类,前者与类型直接关联,后者在外部不可被访问,这两种方法都不可能通过继承或别的方式重写出其他版本,因此它们都适合在类加载阶段进行解析。

invokestatic:调用静态方法。

invokevirtual:调用所有的实例方法。

invokeinterface:调用接口方法,会在运行时再确定一个实现此接口的对象。

Invokedynamic:先在运行时动态解析出调用点限定符所引用的方法,然后再执行该方法,在此之前的4条调用指令,分派逻辑是固化在Java虚拟机内部的,而invokedynamic指令的分派逻辑是向用户所设定的引导方法决定的。在Java

基于栈的指令集与基于寄存器的指令集

Java

基于栈的指令集主要的优点就是可移植,寄存器由硬件直接提供,程序直接依赖这些硬件寄存器则不可避免地要受到硬件的约束。

使用栈架构的指令集,用户程序不会直接使用这些寄存器,就可以由虚拟机实现来自行决定把一些访问最频繁的数据(程序计数器、栈顶缓存等)放到寄存器中以获取尽量好的性能,这样实现起来也更加简单一些。栈架构的指令集还有一些其他的优点,如代码相对更加紧凑(字节码中每个字节就对应一条指令,而多地址指令集中还需要存放参数)、编译端实现更加简单(不需要考虑空间分配的问题,,所需空间都在栈上操作)等。

拿望远镜看别人,拿放大镜看自己。

虚拟机字节码执行引擎】

相关文章:

你感兴趣的文章:

标签云: