字节码执行引擎

物理机的执行引擎是建立在处理器、硬件、指令集和操作系统层面上的。虚拟机的执行引擎是自己实现的,可以自行指定指令集和执行引擎结构体系,并且能够执行不被硬件支持的指令集格式。

输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果

一、运行时栈帧结构

栈帧是用于支持虚拟机进行防腐调用和方法执行的数据结构,是虚拟机运行时数据区中的虚拟机栈中的栈元素存储了方法的局部表量、操作数栈、动态链接、方法返回地址和一些额外的附件信息。

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

1.局部变量表

一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量

程序编译为Class文件时,方法的Code属性中的max_locals数据项就是局部变量表的最大容量。

变量槽是局部变量表的最小单位,int、short、boolean等32位数据类型占一个槽位,long、double占2个槽位。

方法执行时,虚拟机使用局部变量表完成参数值到参数变量表的传递过程。如果执行的是实例方法(非static),0位索引默认的是传递对象实例的引用”this“。其余参数按照参数列表排列,从1开始的局部变量槽,再根据内部变量顺序和作用域分配槽位。

局部变量定义了但没有赋初始值不能使用。

2.操作数栈

也称为操作栈,是后入先出的栈。最大深度在编译时写入Code属性的max_stacks数据项中。

32位数据类型占栈容量为1,64位数据类型占栈容量2.

在一个方法刚开始执行的时候,操作数栈是空的,随着方法的执行,会有各种字节码往操作数栈中写入和提取内容,也就是出栈/入栈操作。

Java 虚拟机的解释执行引擎称为"基于栈的执行引擎",其中所指的"栈"就是操作数栈。

3.动态链接

每个栈帧都包含一个指向运行时常量池中所属方法的引用,持有这个引用为了支持方法调用过程中的动态链接。

符号引用一部分在类加载阶段或者第一次使用的时候转化为直接引用,称为静态解析。另一部分在每一次运行期间转化为直接引用,称为动态链接。

4.方法返回地址

方法退出时,需要返回到方法被调用的位置,程序才能执行,方法返回时可能在栈帧中保存一下信息,用来恢复上层方法的执行状态。正常退出时,调用者的PC计数器的值可以作为返回地址;异常退出时,返回地址通过异常表确定。

方法退出的过程等同于当前栈帧出栈:恢复上层方法的局部变量表和操作数栈,返回值压入调用者栈帧的操作数栈中,调用PC计数器值指向方法调用指令后面的一条指令等。

二、方法调用

唯一作用是确定被调方法的版本。方法调用在Class文件存储的都是符号引用,而不是方法在实际运行时内存布局中的入口地址。

1.解析

调用目标在程序代码写好、编译器进行编译时就必须确定下来,运行期不可改。这类方法的调用称为解析。

调用字节码指令:

invokestatic:调用静态方法
invokespecial:调用实例构造器<init>方法、私有方法和父类方法
invokevirtual:调用所有的虚方法
invokeinterface:调用接口方法,在运行时在确定一个实现此接口的对象
invokedynamic:现在运行时动态解析出调用点限定符所引用的方法,然后再执行该方法

invokestaticinvokespecialinvokeinterface以及invokeinterface指令的分派逻辑是固化在Java虚拟机内部的。invokedynamic是有用户所设定的引导方法决定的。

非虚方法:

静态方法、私有方法、实力构造器、父类方法、final修饰的方法(虽然被invokevirtual指令调用)

解析调用是一个静态的过程,在编译期间就完全确定,在类加载的解析阶段会把涉及的符号引用全部转变为明确的直接引用,不比延迟到运行期再去完成。

2.分派

静态分派

Human man = new Man();

”Human“称为变量的静态类型,”Man“称为变量的实际类型。静态类型的变化是在使用时发生,变量本身的静态类型不会改变,并且最终的静态类型是在编译期可知的实际类型变化的结果在运行期才可确定,编译器在编译时不知道对象的实际类型是什么。

所有依赖静态类型来定位方法执行版本的动作称为静态分派。方法重载是典型应用,虚拟机在重载时是通过参数的静态类型而不是实际类型作为判定依据的。

动态分派

运行期根据实际类型确定方法执行版本的分派称为动态分派。方法重写是典型应用。

动态分派的方法版本选择过程需要运行时在类的方法原数据搜索适合的目标方法,基于性能考虑,为类在方法去建立一个虚方法表,使用虚方法表索引来代替元数据查找。虚方法表中放着方法的实际入口地址,如果方法在子类中没有被重写,则子类与分类的地址入口是一致的。如果重写了,子类方发表中的执行子类实现版本的入口地址。



方法表一般在类加载的连接阶段进行初始化,准备了类的变量初始值后,虚拟机会把该类的方法表也初始化完毕。

单分派与多分派

方法的接收者与参数统称为方法的宗量。

单分派是根据一个宗量对目标方法进行选择,多分派是根据多于一个宗量对目标方法进行选择。

Java语言的静态分派是多分派类型,动态分派是单分派类型。

三、基于栈的字节码解释执行引擎

计算1+1的结果

基于栈的指令集:

两条iconst_1指令连续把两个常量1压入栈后,iadd指令把栈顶的两个值出栈、相加,把结果放回栈顶,最后把istore_0把栈顶的值放到局部变量表的第0个Slot中。

  iconst_1
  iconst_1
  iadd
  istore_0

基于寄存器的指令集:

mov指令把eax寄存器的值设为1,add指令把这个值加1,结果保存在exa寄存器中。

mov eax, 1
add eax, 1

基于栈的解释器执行过程

    public int calc() {
        int a = 100;
        int b = 200;
        int c = 300;
        return (a + b) * c;
    }

javap -verbose查看字节码文件




最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容