`

14、执行引擎

    博客分类:
  • java
 
阅读更多
javac编译器将java文件编译成class文件。而字节码文件再经过类加载器加载、验证、准备、解析、初始化等阶段能被实例使用。
执行引擎主要就是jvm栈和本地方法栈的运作管理;

运行时栈帧结构:
        栈帧(stack frame)是用于支持虚拟机进行方法调用和方法执行时的数据结构,它是虚拟机运行时数据区中的虚拟机栈的栈元素。
        一般把动态连接、方法返回值、和其他信息归档为栈帧信息;
        栈帧包含了局部变量表、操作数栈、动态连接、方法返回地址和一些额外的附加信息。编译后的class文件,栈帧中需要多大的局部变量表、多深的操作数栈都已经完全确定,并且写入到方法表的Code属性之中,因此一个栈帧需要分配多少内存,不会受到程序运行期变量数据的影响,而仅仅取决于具体的虚拟机实现。每一个方法从调用开始到执行完成的过程,就对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。

对于执行引擎来讲,活动线程中,只有栈顶的栈帧是有效的,称为当前栈帧(Curren Stack Frame),这个栈帧所关联的方法称为当前方法(Current Method)。

1、局部变量表(local variable table):
        用于存放方法参数和方法内部定义的局部变量。
        局部变量表的容量以变量槽(variable slot)为最小单位,jvm规范规定slot应该存放一个boolean,byte,short,int,char,float,reference,returnAddress类型的数据,而没有限定slot的分配内存大小,对于64位的数据类型只有double,long两种(reference可能为32位也可能为64位),这两种类型占用两个slot。
       虚拟机使用局部变量表完成参数传递,如果是实例方法(非static)局部变量表中第0位索引是方法所属对象实例的引用表示this,方法中可以通过this来访问这个隐含的参数。其余参数则按照参数表的顺序来排列,占用从1开始的局部变量slot,参数表分配完毕之后,再根据方法体内部定义的局部变量顺序和作用域分配其余的slot。
       为了尽可能节省栈帧空间,局部变量中的slot可以重用,方法体中定义的变量作用域可能不会整个方法体,如fun(){{int a ;}} ,当字节码pc计数器超过了某个值,这个slot就会交给其他变量使用,但在某些情况下会影响gc收集行为;

main(){ 

byte[] nowa = new bate[10*1024*1024]; 

//int a =0; 
System.gc(); 
}}
  如果不执行int a = 0这条语句,slot就没有回收,这个零值很有意义:如果nowa是个大对象/大对象数组,占耗很大的内存而不及时清空将影响jvm整体的运行速度,手动设零值,释放内存;java一本非常著名的书籍《practical java》说到"把不使用的对象应手动赋值为null";

2、操作栈数
        operand stack 也称为操作栈,遵循先入先出(FIFO),同局部变量一样,操作数栈的最大深度在编译时就确定,写入到Code属性的max_stacks数据项中,操作数栈的每一个元素可以使任意的java数据类型,包括long和double型,32位数据类型所占的栈容量为1,64位数据类型所占栈容量为2;
         当一个方法开始执行时,这个方法的操作数栈是空的,在方法执行过程中,会有各种字节码指令向操作数栈中写入和提取内容。比如,加法的字节码指令iadd在运行时会将栈顶两个元素(栈帧)相加并出栈,再将结果入栈。
在编译器和校验阶段的保证下,操作数栈中元素的数据类型必须与字节码指令的序列严格匹配;在大多数vm会将连续的2个栈帧做出部分重叠,重叠部分为部分局部变量表,使用时共用一个变量表,无须额外传递参数;
3、动态连接dynamic linking
        每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用(方法区),持有这个引用是为了支持方法调用过程中的动态连接。
        常量池中的方法符号引用,方法符号在类加载阶段(加载、验证、准备、解析、初始化)或者第一次使用时转化为直接引用,这种转化称为静态解析;若在每次运行时都要转换为直接引用的称为动态连接;

4、方法返回地址
有两种方式退出当前执行的方法:
一是执行引擎遇到任意一个方法返回的字节码指令,这种方法称为正常完成出口。
二是在方法执行过程中遇到无法处理的异常,这种方法称为异常完成出口。

无论哪种方法,方法退出后,都需要返回到调用者的位置,正常退出时,调用者的PC计数器值可以作为返回地址,栈帧会保存这个计数器值,而异常退出时,返回地址要通过异常处理器表来确定。
方法退出的过程实际上是将当前栈帧出战,并恢复上层方法的局部变量表和操作数栈,把返回值传入调用者的操作数栈中,调整pc计数器值、

5、 栈帧信息
5.1、 方法调用
方法调用不等于方法执行,方法调用阶段(这是阶段)其唯一的任务就是确定要执行的那个具体方法,暂时不会执行运行;一切方法在字节码里都是引用符号,而不是实际方法的入口(直接引用),这个特性给了java强大的扩张能力,如动态代理,但也使java调用过程变得更复杂,在类加载阶段和运行时才能确定直接引用!

5.2、解析(阶段)
所用被调用的方法在字节码文件里都是一个符号引用,在类加载阶段,有的会转化为直接引用,而有的要执行时才转化为直接引用,在加载阶段转化的条件:方法是一个可确定的调用版本,并且这个方法的调用版本是固定的,这个方法会在编译时就确定下了,这类方法的调用称为解析。
JVM提供了4条方法调用的字节码指令:
invokestatic:调用静态方法
invokespecial:调用实例构造器<init>方法,私有方法和父类方法
invokevirtual:调用所有的虚方法
invokeinterface:调用接口方法,会在运行时再确定一个实现此接口的对象。
invokedynamic
解析阶段是将(唯一确定的)方法加载到方法区,并不会执行, 能被invokestatic和invokespecial调用的方法,即可在解析阶段加载,他们是唯一确定的,这4类方法称为实方法,其他方法称为虚方法;
编写一个static方法:
Java代码  收藏代码
public class Demo{ 
  public static void say(){ 
     System.out.println("ok"); 
     } 
public static void main(String... s){ 
Demo.say(); 


用javap -verbose Demo.class打开 
public Demo(); 
1: invokespecial #1                  // Method java/lang/Object."<init>":()V 
public static void say(); 
0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream; 
5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
public static void main(java.lang.String...); 
0: invokestatic  #5                  // Method say:()V 

5.3、分派
java的3个基本特征:继承、封装、多态;方法的重载和重写。
1,静态分派(static dispatch)---重载
Parent father = new Son();
Parent被称为静态类型(Static Type)或者叫外观类型(Apparent Type),,Son称为实际类型(Actual Type)。
虚拟机(编译器)重载时通过参数的静态类型作为判断依据。所有依赖静态类型来定位方法执行版本的分派动作,都称为静态分派;
Java代码  收藏代码
Demo d = new Demo(); 
d.say(w); 
d.say(m); 
两次调用d的say方法,编译器重载say方法(第一次叫加载,第二次叫重载),通过参数的静态类型做出方法重载(方法重载:1.参数类型,2.参数数量),依靠参数来定位方法执行版本的分派动作,都称为静态分派。静态分派的最典型应用就是方法重载。 静态分派发生在编译阶段,静态分派操作不是由虚拟机执行,编译器重载时确定重载版本("最适合的版本")。
Java代码  收藏代码
void say(Object obj){} 
void say(char c){}<strong style="color: #ff0000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 1.5; background-color: white;"> </strong> 
比如 say('a');会执行第二个方法而不是第一个,因为在方法重载时编译器确定了第二个方法是最适合的版本,而非第一个say()方法;
当出现编译器无法确定该采用何种版本时将拒绝编译。
2,动态分派()---重写
在运行期间,jvm根据实际类型确定方法执行版本的分派过程称为动态分派。
动态分派实现手段“稳定优化”,在类的方法去中建立一个虚方法表(Vritual Method Table,vtable在invokeinterface执行时用用到接口方法表Interface Method Table,itable),使用虚方法表索引来代替元数据查找以提高性能。虚方法表中存放着各个方法的实际入口地址,如果某个方法在子类中没有被重写,那么子类的虚方法表里的入口和父类虚方法入口地址是相同的,都指向父类的入口地址,如果子类重写了父类方法,子类的方法表中保存重写后的方法入口。

3,单分派和多分派
方法(int x = fun(int a,int b);)的接收方x和方法的参数a,b称为方法的宗量,分派基于宗量的种类,分为单分派和多分派两种;
“java语言是一门静态多分派(方法重载多分派)、动态单分派的语言(方法重写单分派)”;
在两个say()方法中,存在不同的静态类型:Object和Character,这里宗量是2个,故为多分派类型;
方法表一般在准备阶段初始化,在类变量完成初始零值赋值之后,jvm把实方法,虚方法也进行加载,但不执行。

6、动态语言支持---invokedynamic指令
  • 大小: 9.6 KB
分享到:
评论

相关推荐

    wasabi-aeg:使用符号执行引擎Triton的AEG(自动漏洞生成)的另一种实现方式

    这是使用符号执行引擎Triton的AEG(自动漏洞生成)的另一种实现方式,并且仅是概念证明。 该项目的灵感来自以下研究。 简报 女孩遇见象征性的处决:断言2.自动利用漏洞的产生(在第14回カー/ル/ VM探[队)[ , ]...

    IGE引擎升级版

    14、修改登陆器公告打开时执行公告地址。 15、添加游戏备用列表功能。 16、取消登陆器选择窗口化模式时变换16位真彩色,已经修改到游戏内核运行。 17、取消登陆器跟配置器的加密系统文件,全部修改为明文! 18、修改...

    Drools规则引擎从入门到精通

    9 Drools WorkBench使用9.1 WorkBench基本使用9.2 创建会话9.3 编译并部署9.4 执行代码10 Drools决策表入门11 Drools决策表加强12 Drools决策表整合Springboot和MybatiesPlus13 动态编译Class文件实现Drools规则调用...

    Sphinx搜索引擎架构与使用文档(和MySQL结合)V1.1.

    7、配置服务器开机启动时需要自动执行的命令(以db11为例) 14 8、创建Sphinx存储引擎表: 14 ⑴、设置/etc/hosts 14 ⑵、登录运行在3306端口的MySQL服务器(提供“搜索查询服务”): 14 ⑶、创建数据库“Sphinx”...

    大纲及下载地址.doc

    07 - Hive底层执行引擎深度剖析 08 - 全宇宙最强的25条Hive性能调优实战 09 - Kafka消息引擎底层架构深度剖析 10 - Kafka高性能的消息封装 11 - Kafka客户端容错体系源 12 - Kafka服务端高性能架构设计源码剖析 13 -...

    轻量级的嵌入式FaaS引擎(可按需组装),也可用作低代码引擎

    我是一个嵌入式 FaaS 引擎 + 扩展中心 + 发布系统。(与云服务的FaaS有区别)。运行实例 + 安装几个扩展插件,等于一个性化系统。兼容jdk8, jdk9, jdk10, jdk11, jdk12, jdk13, jdk14。通过统一的接口嵌入,促成各种...

    Mysql性能优化教程

    存储引擎类型 14 内存使用考量 14 性能与安全性考量 14 存储/写入压力优化 15 运维监控体系 15 Mysql 架构优化 17 架构优化目标 17 防止单点隐患 17 方便系统扩容 17 安全可控,成本可控 17 分布式方案 18 分库&拆表...

    applem2_20120610苹果引擎配套工具,内有登陆器配置

    14、增加使用技能触发功能,详情请查看帮助文档 使用某技能自身触发. Q-Function.txt中[@MagSelfFuncX]段,其中X表示要触发的魔法ID 对目标人物使用技能时,自己触发. Q-Function.txt中[@MagTagFuncX] 段,其中X表示...

    详解js模板引擎art template数组渲染的方法

    JavaScript 模板引擎作为数据与界面分离工作中最重要一环,越来越受开发者关注,模板引擎种类也是五花八门,我就说几个安全性高、错误处理调试优,执行速度快的有artTemplate(腾讯 14k)、juicer(国外 12k)这俩个,...

    phpStudy 14种合集 自由切换 + phpfind + phpLight(解压版)

    14种合集 自由切换 PHP 5.2.17 新型的CGI程序编写语言,易学易用、速度快、跨平台。 PHP 5.3.26 新型的CGI程序编写语言,易学易用、速度快、跨平台。 PHP 5.4.16 新型的CGI程序编写语言,易学易用、速度快、跨...

    深入java虚拟机中文第2版

    本书共分20章,第1-4章解释了Java虚拟机的体系结构,包括Java栈、堆、方法区、执行引擎等;第5-20章深入描述了Java技术的内部细节,包括垃圾收集、Java安全模型、Java的连接模型和动态扩展机制、class文件、运算及...

    基于RuoYi-VUE版本开发的OA协同办公系统源码 集成Flowable流程引擎

    12.定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 13.代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 14.系统接口:根据业务代码自动生成相关的api接口文档。 15.服务监控:...

    完结14章Flink 从0到1实战实时风控系统

    例如,业务风控定义了一个风控规则a+b&gt;5,在规则引擎上执行的时候需要知道a,b的值,这两个值的获取一般需要通过大数据获得,然后在规则引擎上执行,从而得到结果是否命中,以及执行命中后的操作。

    funsui14:九州大学喷泉项目'14

    当你想编译这些文件时,在终端上切换到这个下载文件夹的目录并执行以下命令。 发布文件夹是输出。 npm install # node.js の依存ファイルをダウンロード gulp # release フォルダに出力 还准备了以下命令。 gulp...

    opencv-4.4.0-vc14_vc15.exe

    opencv-4.4.0-vc14_vc15.exe 版本:4.4.0 2020年7月 OpenCV 4.x的夏季更新已发布 :晴天: 此版本的亮点: SIFT(尺度不变特征变换)算法已移至主存储库(SIFT的专利已过期) DNN模块: 改进的图层/激活/支持...

    网络安全培训方案(1).docx

    10)、掌握上传漏洞、命令执行漏洞、XSS漏洞等常见Web漏洞的利用方式及技巧 11)、掌握各类提权方法 12)、掌握各类第三方插件/程度的漏洞利用方法 网络安全培训方案(1)全文共14页,当前为第2页。网络安全培训方案(1...

    先进的HIS软件架构设计,HAP医疗应用软件平台技术白皮书

    1.3 采用工作流引擎技术的业务流程模型 5 2 灵活的适应能力 7 2.1 支持多平台 7 2.2 支持多种后台数据库 8 2.3 支持多种客户端类型 8 3 强大的二次开发能力 9 3.1 产品化和项目化相结合 9 3.2 开放的体系架构和插件...

    nodeJs安装教程

    简单的说 Node.js 就是运行在服务端的 JavaScript。...Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。 以下文档是nodejs的安装教程。

    光学识别 OCR 软件 Readiris Corporate 17.2.9.0 中文多语直装版.zip

    利用 Readiris 14 中的扫描精灵就能轻易扫描您的纸质文件,并无需执行其他的扫描软件。您将体验从没体验过如此轻易就能把文档进行扫描! 从数码相机或手机进行导入图档,并即时转换到可供编辑及搜索的 PDF 文档! 9...

    ASP 小程序 权限 管理 数据库 等级 加密 搜索 探针

    6月25日 7:21 1458 SQL执行命令.rar 12月27日 8:44 5939 Star1草稿自动保存挂件(AJAX & XML).rar 10月8日 13:09 28524 tylink11.rar 12月24日 14:50 89720 ULUS10114001.rar 10月8日 1:29 65364 waitme的小偷...

Global site tag (gtag.js) - Google Analytics