深入了解java虚拟机(JVM) 第十三章 虚拟机字节码执行引擎
一、概述
执行引擎是java虚拟机最核心的组成部件之一。虚拟机的执行引擎由自己实现,所以可以自行定制指令集与执行引擎的结构体系,并且能够执行那些不被硬件直接支持的指令集格式。所有的Java虚拟机的执行引擎都是一致的:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果。本节将主要从概念模型的角度来讲解虚拟机的方法调用和字节码执行。
二、运行时栈帧结构
1.什么是栈帧
栈帧也叫过程活动记录,是编译器用来进行方法调用和方法执行的一种数据结构,它是虚拟机运行是数据区域中的虚拟机栈的栈元素。
栈帧包括了局部变量表、操作数栈、动态链接、方法返回地址和额外的一些附加信息。
在编译过程中,局部变量表的大小已经确定,操作数栈深度也已经确定,因此栈帧在运行的过程中需要分配多大的内存是固定的,不受运行时影响。
对于的有逃逸的对象也会在栈上分配内存,对象的大小其实在运行是也是确定的,因此即使出现了栈上分配,也不会改变栈帧大小。
栈帧的结构图如下:
一个线程中,可能调用链会很长,很多方法都同时处于执行状态。对于执行引擎来讲,活动线程中,只有栈顶的栈帧是最有效的,称为当前栈帧,这个栈帧所关联的方法称为当前方法。执行引擎所运行的字节码指令反对当前栈帧进行操作。
2.局部变量表
局部变量表是一组变量值存储空间,用于存放方法参数和方法内定义的局部变量。局部变量表的容量以变量槽(Variable Slot)为最小单位。 一个Slot可以存放一个32位以内(boolean、byte、char、short、int、float、reference和returnAddress)的数据类型,reference类型表示一个对象实例的引用,returnAddress已经很少见了,可以忽略。
需要注意的是:
1)局部变量表没有初始值,要使用局部变量,必须先赋值
2)slot复用问题。当一个变量的PC寄存器的值大于slot的作用域的时候,slot是可以复用的,这样的话就会导致JVM难以回收,所以在使用对象完后,要把对象指定为null,这样才会方便垃圾回收。
3.操作数栈
操作数栈(Operand Stack) 也常称为操作栈,它是一个后入先出栈。当一个方法执行开始时,这个方法的操作数栈是空的,在方法执行过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是 出栈/入栈操作。
在概念模型中,一个活动线程中两个栈帧是相互独立的。但大多数虚拟机实现都会做一些优化处理:让下一个栈帧的部分操作数栈与上一个栈帧的部分局部变量表重叠在一起,这样的好处是方法调用时可以共享一部分数据,而无须进行额外的参数复制传递。
4.动态连接
指向该栈所属的方法。
5.方法返回地址
方法调用时通过一个指向方法的指针指向方法的地址,方法返回时将回归到调用处,那个地方就是返回地址。
6.附加信息
虚拟机规范中允许具体的虚拟机实现增加一些规范里没有描述的信息到栈帧中。这部分信息完全取决于虚拟机的实现。
三、方法调用
方法调用不等同于方法的执行,方法调用阶段的唯一任务就是确定被调用方法的版本。
方法调用阶段的目的:确定被调用方法的版本(哪一个方法),不涉及方法内部的具体运行过程,在程序运行时,进行方法调用是最普遍、最频繁的操作。一切方法调用在Class文件里存储的都只是符号引用,这是需要在类加载期间或者是运行期间,才能确定为方法在实际 运行时内存布局中的入口地址(相当于之前说的直接引用)。
1.解析
在类加载的解析阶段,会将其符号引用转化为直接引用(入口地址),这类方法的调用称为“解析(Resolution)”。
在java中的解析调用:
1)静态方法
2)构造器方法
3)私有方法
4)final修饰的方法
2.静态分配调用(方法的重载)
1)方法调用选择静态类型的方式称为静态分派,看下面一个例子
package com.example.demo; public class Demo {
/**
*
* 创建两个类
*
*/
static class Parent{}
static class Son extends Parent{} /**
*
* 对show方法进行两种不同参数的重载
*/
public static void show(Parent p) {
System.out.println("这是Parent方法");
}
public static void show(Son s) {
System.out.println("这是Son方法");
} public static void main(String[] args) {
//创建了一个Parent类,他的实例P的静态类型和实际类型都是Parent
Parent p = new Parent();
//令p等于Son类型,此时P的静态类型为Parent,实际类型都是Son
p = new Son();
//方法重载时,方法调用选择的是静态类型,所以此时调用的是Parent参数
show(p);
//将P的静态类型强制转化为Son,此时P的静态类型为Son,实际类型都是Son
//方法重载时,方法调用选择的是静态类型,所以此时调用的是Son参数
show((Son) p);
} }
输出的结果是:
2)方法调用中,传递的实参的数据类型和方法的形参的数据类型类型不一定要一致,如果实参和形参的数据类型不同,则会优先选择与实参数据类型匹配度最高的形参数据类型方法进行调用,
需要注意的是:形参和实参的数据类型必须是能够相互转换的数据类型,看下面的一个例子
package com.example.demo; public class Demo { /**
*
* 对show方法进行多种不同参数的重载
*/ public static void show(float a) {
System.out.println("这是float方法");
}public static void show(Object b) {
System.out.println("这是Object方法");
} public static void main(String[] args) {
int a=0;
String b="b";
show(a);
show(b);
} }
输出结果:
3.动态分派调用(方法的重写)
方法调用选择的实际类型的方式称为动态分派。
package com.example.demo; public class Demo {
/**
*
* 创建一个父类和其show方法
*
*/
static class Parent{
public void show() {
System.out.println("这是Parent方法");
}
}
/**
*
* 创建一个子类并重写父类的show方法
*
*/
static class Child extends Parent{
@Override
public void show() {
System.out.println("这是Child方法");
}
} public static void main(String[] args) {
//创建了一个parent实例,这个实例的静态类型为parent,实际类型为Child
Parent parent=new Child();
//方法的重写选用的是实例的实际类型
parent.show(); } }
输出结果为:
参考文档:https://www.cnblogs.com/snailclimb/p/9086337.html
深入了解java虚拟机(JVM) 第十三章 虚拟机字节码执行引擎的更多相关文章
- 深入理解Java虚拟机(类文件结构+类加载机制+字节码执行引擎)
目录 1.类文件结构 1.1 Class类文件结构 1.2 魔数与Class文件的版本 1.3 常量池 1.4 访问标志 1.5 类索引.父索引与接口索引集合 1.6 字段表集合 1.7 方法集合 1 ...
- 深入理解Java虚拟机读书笔记5----虚拟机字节码执行引擎
五 虚拟机字节码执行引擎 1 运行时栈帧结构 ---栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,是虚拟机运行时数据区中的虚拟机栈的栈元素. ---栈帧中存储了方法的局部变 ...
- 《深入理解Java虚拟机》-----第8章 虚拟机字节码执行引擎——Java高级开发必须懂的
概述 执行引擎是Java虚拟机最核心的组成部分之一.“虚拟机”是一个相对于“物理机”的概念 ,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器.硬件.指令集和操作系统层面上的,而 ...
- 深入理解Java虚拟机(字节码执行引擎)
深入理解Java虚拟机(字节码执行引擎) 本文首发于微信公众号:BaronTalk 执行引擎是 Java 虚拟机最核心的组成部分之一.「虚拟机」是相对于「物理机」的概念,这两种机器都有代码执行的能力, ...
- 深入理解JVM虚拟机5:虚拟机字节码执行引擎
虚拟机字节码执行引擎 转自https://juejin.im/post/5abc97ff518825556a727e66 所谓的「虚拟机字节码执行引擎」其实就是 JVM 根据 Class 文件中给 ...
- 深入理解java虚拟机(5)---字节码执行引擎
字节码是什么东西? 以下是百度的解释: 字节码(Byte-code)是一种包含执行程序.由一序列 op 代码/数据对组成的二进制文件.字节码是一种中间码,它比机器码更抽象. 它经常被看作是包含一个执行 ...
- 【java虚拟机系列】从java虚拟机字节码执行引擎的执行过程来彻底理解java的多态性
我们知道面向对象语言的三大特点之一就是多态性,而java作为一种面向对象的语言,自然也满足多态性,我们也知道java中的多态包括重载与重写,我们也知道在C++中动态多态是通过虚函数来实现的,而虚函数是 ...
- java虚拟机字节码执行引擎
定义 java虚拟机字节码执行引擎是jvm最核心的组成部分之一,它做的事情很简单:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果.在不同的虚拟机实现里,执行引擎在执行java代码 ...
- Java虚拟机--虚拟机字节码执行引擎
Java虚拟机--虚拟机字节码执行引擎 所有的Java虚拟机的执行引擎都是一致的:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果. 运行时栈帧结构 用于支持虚拟机进行方法调用和方 ...
- Java虚拟机-字节码执行引擎
概述 Java虚拟机规范中制定了虚拟机字节码执行引擎的概念模型,成为各种虚拟机执行引擎的统一外观(Facade).不同的虚拟机引擎会包含两种执行模式,解释执行和编译执行. 运行时帧栈结构 栈帧(Sta ...
随机推荐
- python 发送带附件的 邮件
from email.MIMETextimportMIMETextfrom email.MIMEMultipartimportMIMEMultipartimport smtplib mail_host ...
- java.io.CharConversionException: Not an ISO 8859-1 character:
java.io.CharConversionException: Not an ISO 8859-1 character: XXX 这个问题可能是因为outputstream输出中文字造成的影响. r ...
- Redis Key操作
[Redis Key操作] 1.GETSET key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value). 当 key 存在但不是字符串类型时,返回一个错 ...
- 39-python 字符串替换+正则
from bs4 import BeautifulSoup import urllib.request import re moduel =re.compile('<.*?>') st = ...
- 41-邮差送信(dfs)
邮差送信 (15分)C时间限制:1 毫秒 | C内存限制:3000 Kb题目内容: 有一个邮递员要在n个城市之间来回送信.但有的城市之间有大路相连而有的没有路.现在要由一个城市到另一个城市送信,中途 ...
- springboot中开发热部署(devtools)
1.只需要在pom文件中引入devtools的依赖即可 <dependency> <groupId>org.springframework.boot</groupId&g ...
- SqlMapConfig.xml配置文件中的mapper映射器标签
Mapper配置的几种方式: 1. <mapper resource=" "/> 使用相对于类路径的资源 如:<mapper resource="com ...
- Error generating final archive: Unable to get debug signature key
在调试程序时,发生下面的错误: Error generating final archive: Unable to get debug signature key 解决办法: 删除下面的文件: C:\ ...
- 简述json模块
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写,他的数据结构与Python中的字典一样,键值对来表示数据间的关系,可以包含列表. 在编写 ...
- C语言基础第一次作业
一,1)大学和高中最大的不同是没有人天天看着你,请问大学理想的师生关系是?有何感想? 看了邹欣老师博客中写到的教学基础——师生关系后陷入沉思,邹欣老师在她的博客中直接否认了传统认知的师生关系——蜡烛, ...