虚拟机执行子系统-8.虚拟机字节码执行引擎

本文深入探讨Java运行时栈帧结构,包括局部变量表、操作数栈等核心组件,以及方法调用的解析与分派机制,详解静态与动态分派的区别,同时介绍基于栈的字节码执行引擎的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1运行时栈帧结构

1.1局部变量表

1.1.1功能

1.1.2 slot

1.1.3 this

1.2操作数栈

1.3动态连接

1.4方法返回地址(方法出口)

2方法调用

2.1解析

2.2分派

2.2.1静态分派(例如:重载)

2.2.2动态分派(重写)

2.2.3单分派与多分派

2.2.4个人理解

2.2.5虚拟机动态分派的实现

2.3动态类型语言支持(JDK1.7)

2.3.1动态类型语言

2.3.2java.lang.invoke(MethodHandle方法的引用)

2.3.3invokedynamic指令

3基于栈的字节码执行引擎

3.1解释执行

3.2基于栈的指令集和基于寄存器的指令集

3.3基于栈的解释器执行过程

1运行时栈帧结构

1.1局部变量表

1.1.1功能

1.1.2 slot

  • 32位

  • reference类型

  • 64位

long和double

1.1.3 this

1.2操作数栈

1.3动态连接

1.4方法返回地址(方法出口)

方法退出的两个方式:

正常完成出口:遇到方法返回的字节码指令

异常完成出口:方法执行过程中遇到异常,且未在方法内部处理

 

2方法调用

2.1解析

类加载的解析阶段,会将一部分符号引用转化为直接引用,这种转化成功的前提是:

方法在运行之前就有一个可确定的调用版本,且这个调用版本在运行期不可变。这类方法调用称为解析。

  • 5个方法调用字节码指令

  • 虚方法与非虚方法

final方法是非虚方法,虽然final方法由invokevirtual调用

2.2分派(静态或动态)

2.2.1静态分派(例如:重载)

静态分派:依据静态类型来定位方法执行版本

举例:编译器在重载时通过参数的静态类型选择方法执行版本

代码示例片段:

2.2.2动态分派(重写)

实现原理:invokevirtual指令的多态查找过程

重写的方法选择实际类型作为方法执行版本(动态分派)

2.2.3单分派与多分派

方法的宗量:方法的接收者(实际执行者)与方法的参数

  • 静态多分派

  • 动态单分派

 

2.2.4个人理解

在多态中,有一句经典的口诀:编译时看左边,运行时看右边。编译看左边是因为静态分派发生在编译阶段,运行看右边是因为运行时是动态分派。

私货:

Java是静态多分派,动态单分派。所以在动态分派的时候invokevirtual指令需要按继承关系从下往上搜寻方法。我在想,如果是动态多分派,应该就不用搜寻,而是直接定位了,不知道想的对不对。

2.2.5虚拟机动态分派的实现

动态分派需要运行时在类的方法元数据中寻找方法,而动态分派非常频繁,所以虚拟机采用优化手段解决,包括稳定优化和激进优化。

稳定优化:虚方法表

2.3动态类型语言支持(JDK1.7

2.3.1动态类型语言

类型检查主体过程在运行期而非编译期

2.3.2java.lang.invoke(MethodHandle方法的引用)

Java语言不能单独把一个函数作为参数进行传递。

2.3.3invokedynamic指令

看不懂以后补充

 

3基于栈的字节码执行引擎

3.1解释执行

C/C++编译器走下方路径,词法分析、语法分析、优化器及目标代码生成器独立于执行引擎,形成完整的编译器。

Javac编译器完成了字节码指令流之前的过程,解释器在虚拟机内部。

3.2基于栈的指令集和基于寄存器的指令集

  • 基于栈

指令流中的指令大部分都是零地址指令,依赖操作数栈进行工作

优点:可移植

缺点:速度慢(栈实现在内存中,频繁内存访问。以及出入栈操作产生更多指令)

  • 基于寄存器

3.3基于栈的解释器执行过程

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值