JVM-11. 虚拟机字节码执行引擎

JVM-11. 虚拟机字节码执行引擎

1 运行时栈帧

  • 栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构。
  • 位于虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)中的栈元素。
  • 存储了方法的局部变量,操作数栈,动态链接和方法返回地址,额外附加信息
  • 一个方法的调用和执行完成,对应着一个栈帧在虚拟机栈里面入栈到出栈的过程
  • 当前栈帧(Current Stack Frame):栈顶的有效栈帧,与这个栈帧相关联的方法为当前方法(Current Method)。执行引擎运行的所有字节码指令都只针对当前栈帧操作。

1.1 局部变量表

  • 局部变量表(Local Variable Table)是一组变量值存储空间,用于存放方法参数和方法内部的局部变量
  • 编译期在方法的Code属性的max_locals数据项中确定了方法所需要分配的局部变量表的最大容量
  • 局部变量表的最小单位是变量槽(Variable Slot),简称Slot
  • 方法执行时,虚拟机是使用局部变量表来完成参数值到参数变量列表的传递的:
    实例方法的局部变量表第0位索引的slot默认是用于传递方法所属对象实例的引用,方法中使用关键字this访问这个隐含的参数。其余参数占位从1开始的局部变量slot

1.2 操作数栈

  • 操作数栈(Operand Stack) 也被称为操作数栈,是一个后入先出(LIFO)栈。
  • 最大深度在编译时写入到Code属性的max_stacks数据项中
  • 操作数栈中的元素是任意的Java数据类型
  • 操作数栈中的元素数据类型必须和字节码指令的序列严格匹配
  • 虚拟机可能对栈帧作出一些共享,让下面栈帧的操作数栈帧和上面栈帧的部分局部变量表重合,从而共用部分数据

1.3 动态链接

  • 栈帧包含一个运行时常量池中改帧所属方法的引用
  • 目的是为了支持方法调用过程中的动态链接(Dynamic Linking)

1.4 方法返回地址

  • 方法开始执行后,两种方法退出:
    • 执行引擎遇到任意一个方法返回的字节码指令,此时可能有返回值传递给上层方法调用者,被称为正常完成出口(Normal Method Invocation Completion)
    • 在方法执行过程中遇到异常,并且异常没有在方法体内得到处理,被称为异常完成出口(Abrupt Method Invocation Completion),这种方法退出不会传递给上层调用者任何返回值
  • 方法退出过程实际上等同于把当前栈帧出栈

1.5 附加信息

  • JVM规范允许JVM增加一下额外信息到栈帧中,例如调试相关的信息

2. 方法调用

方法调用不等于方法执行,调用的唯一任务是确定调用方法的版本。

2.1 解析

  • 方法调用的目标方法在Class文件中是一个常量池的中的符号引用
  • 类加载阶段,一部分符号引用转化为直接引用,前提条件是:方法在程序真正运行之前就有一个可确定的调用版本,且在运行期不可变。
  • 这类方法的调用称为“解析(Resolution)”
  • 主要有静态方法和私有方法两大类,前者与类型直接关联,后者在外部不可被访问。因此他们都不可能通过继承或者其他方式重写为其他版本
  • 解析过程一定是一个静态过程,在编译期间就完全确定

2.2 分派

分派实现了多态性特征的最基本的体现。

2.2.1 静态分派

静态分派和方法重载有很密切的联系。

  • 静态类型(Static Type)外观类型(Apparent Type)和实际类型(Actual Type)在程序中都有可能发生一些变化,区别是静态类型的变化仅仅在使用时发生,变量本身的静态类型不会被改变,且最终的静态类型在编译器可知;实际类型的变化结果在运行时才可确定。
  • 重载时通过参数的静态类型而不是实际类型作为判断依据。
  • 所有依赖静态类型来定位方法执行版本的分派动作成为静态分派。例如方法重载。
  • 静态分派发生在编译阶段。
  • 字面量不需要定义,所以字面量没有显示的静态类型,只能通过语言上的规则理解和推断。产生了重载方法的匹配优先级。

2.2.2 动态分派

动态分派和方法重写有很密切的联系。

  • 在运行期间根据实际类型确定方法执行版本的分派过程成为动态分派。
  • 依据invokevirtual指令实现,吧常量池中的类方法符号引用解析到了不同的直接引用上。

2.2.3 单分派与多分派

  • 方法的接受者与方法的参数统称为方法的宗量。
  • 根据分派基于多少中宗量,可以将分派划分成单分派和多分派两种:
    • 单分派是根据一个宗量对目标方法进行选择
    • 多分派是根据多个宗量对目标方法进行选择。
  • Java静态分派属于多分派类型
  • Java动态分派属于单分配类型

2.3 动态类型语言支持

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

推荐阅读更多精彩内容