重读《深入理解Java虚拟机》五、虚拟机如何执行字节码?程序方法如何被执行?虚拟机执行引擎的工作机制
Class文件二进制字符流通过类加载器和虚拟机加载到内存(方法区)完成在内存上的布局和初始化后,虚拟机字节码执行引擎就可以执行相关代码实现程序所定义的功能。虚拟机执行引擎执行的对象是方法(均特指非本地方法),方法是
着一个程序所定义的一个功能的载体,实现预定的业务功能或者特定的功能等。虚拟机执行引擎就是执行程序方法的一个引擎,一个类的信息通过方法承载了它所担负的功能职责,程序的执行就是一个个方法的执行和相互调用。
方法的内容有:方法名,参数列表,返回值,内部定义的局部变量,方法的可见性,方法内部的执行操作和符号引用等等。虚拟机执行引擎要执行方法,首先就需要用单独的数据结构来存放定义方法签名信息和内部定义的局部变量等。然后
方法内部引用到了外部类或者方法等信息就需要进行相关符号引用的解析,而且在允许方法出现重载的情况下还要特定的机制用来确定最终要执行的方法版本。最后还要告诉底层硬件将要如何执行预定的程序代码。
Java虚拟机内存内针对方法的执行专门划分了一个区域即虚拟机栈。虚拟机栈内通过栈帧结构来存储调用方法和执行方法需要的局部变量,操作数栈、方法返回值等,通过栈帧的出入栈来表示方法的执行顺序。
1、栈帧结构:虚拟机内如何存储方法的内容,方法如何在虚拟机内的表示
栈帧的结构也就是程序方法的结构,栈帧结构存储了方法的内容。栈帧的出栈入栈代表了方法的执行过程和方法执行模型。
|
栈帧组成 |
用途、作用、功能 |
特点 |
其他 |
| 局部变量表 | 变量值存储空间,用于存放方法需要的参数和局部变量 | 以变量槽Slot为最小单位,每个Slot存储特定类型的数据信息,且可重用 局部变量表内的变量在虚拟机类的加载过程中不进行系统默认值初始化。 |
静态方法: 实例方法:第0位索引存放方法所属对象实例的引用 |
| 操作栈 | 用于存放字节码操作指令执行所需要的操作数值和操作执行结果值 | 32位数据占用1个操作栈,64位数据占用两个操作栈 | |
| 动态连接 | 运行期将相关的符号引用转换为直接引用 | 静态连接:在类加载或者第一次使用的时候转换为直接引用 | 栈帧信息 |
| 返回地址 | 方法执行完成的结果值 | 栈帧信息 | |
| 附加信息 | 附加到栈帧上的一些信息 | 栈帧信息 |
2、方法的调用:解析方法的符号引用和确定方法的版本
(1)虚方法和非虚方法
只有在允许方法重载的情况下才有虚方法和非虚方法之分,因为在允许重载的情况下方法的版本不止一个,在方法的执行前需要特定的机制确定将要执行的方法版本。
非虚方法:能够在解析阶段(将符号引用转换为直接引用)确定方法执行版本的方法。在解析阶段能够确定方法版本的有:静态方法,私有方法,实例构造器,父类方法,final修饰的方法
虚方法:只有在运行期才能够最终确定方法执行版本的方法。
(2)解析
方法调用时,方法执行前将方法内的符号引用转换为直接引用的过程
解析调用时一个静态的过程,在编译期内就能够完全确定。类加载过程中解析阶段就会把涉及的符号引用直接转换为直接引用。
(3)分派
确定方法最终调用的版本的步骤。
1)静态分派和动态分派:
静态分派(编译期分派):在编译期根据静态类型来定位方法执行的版本的分配过程,因为静态类型在编译期可知.Java虚拟机方法重载的规则就是根据参数的静态类型确定最终执行的方法版本的。
动态分派(运行期分派):在运行期根据实际类型来确定最终执行的方法版本的分派过程
2)方法的重载和重写
3、虚拟机如何执行方法?虚拟机执行引擎的工作机制
(1)解释执行(通过解释器执行)
|
指令集 |
优点 |
缺点 |
应用情况 |
| 基于栈的指令集 | 可移植,代码相对紧凑、编译器实现简单 | 执行速度慢 | |
| 基于寄存器的指令集 | 受硬件约束大,不可移植性 | 执行速度快 | 主流物理机采用 |
(2)编译执行(通过JIT编译器产生本地代码执行)

重读《深入理解Java虚拟机》五、虚拟机如何执行字节码?程序方法如何被执行?虚拟机执行引擎的工作机制的更多相关文章
- JVM总结-虚拟机怎么执行字节码
1. JRE,JDK JRE : 包含运行 Java 程序的必需组件,Java 虚拟机+ Java 核心类库等. JDK : JRE + 一系列开发.诊断工具. 2. java字节码 编译器将 Ja ...
- 深入理解Java AIO(二)—— AIO源码解析
深入理解Java AIO(二)—— AIO源码解析 这篇只是个占位符,占个位置,之后再详细写(这个之后可能是永远) 所以这里只简单说一下我看了个大概的实现原理,具体的等我之后更新(可能不会更新了) 当 ...
- Java安全之动态加载字节码
Java字节码 简单说,Java字节码就是.class后缀的文件,里面存放Java虚拟机执行的指令. 由于Java是一门跨平台的编译型语言,所以可以适用于不同平台,不同CPU的计算机,开发者只需要将自 ...
- JVM总结(五):JVM字节码执行引擎
JVM字节码执行引擎 运行时栈帧结构 局部变量表 操作数栈 动态连接 方法返回地址 附加信息 方法调用 解析 分派 –“重载”和“重写”的实现 静态分派 动态分派 单分派和多分派 JVM动态分派的实现 ...
- 【JDK命令行 一】手动编译Java源码与执行字节码命令合集(含外部依赖引用)
写作目标 记录常见的使用javac手动编译Java源码和java手动执行字节码的命令,一方面用于应对 Maven 和 Gradle 暂时无法使用的情况,临时生成class文件(使用自己的jar包):另 ...
- 《深入理解Java虚拟机》学习笔记之字节码执行引擎
Java虚拟机的执行引擎不管是解释执行还是编译执行,根据概念模型都具有统一的外观:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果. 运行时栈帧结构 栈帧(Stack Frame) ...
- 8.5(java学习笔记)8.5 字节码操作(javassist)
一.javassist javassist让我们操作字节码更加简单,它是一个类库,允许我们修改字节码.它允许java程序动态的创建.修改类. javassist提供了两个层次的API,基于源码级别的和 ...
- 记一次使用修改字节码的方法解决java.lang.NoSuchMethodError
接兔兔国际sdk ane 充值界面选择兔币充值就会闪退, 观察logcat 04-19 10:10:54.224: E/AndroidRuntime(20315): FATAL EXCEPTION: ...
- Java Eclipse编译后产生的字节码文件,用DOS命令符怎么打开
在很多初学者刚刚接触eclipse的时候,写完一个代码文件.例如 Demo.java 通过run as a java application生成之后,会产生一个Demo.class. Demo.cla ...
随机推荐
- MAC OS查看端口占用情况及杀死进程
终端命令 sudo lsof -i :9000 COMMAND PID USER FD TYPE DEVICE ...
- c# 调用非托管c++dll 参数问题(转)
在C#中调用C(C++)类的DLL的时候,有时候C的接口函数包含很多参数,而且有的时候这些参数有可能是个结构体,而且有可能是结构体指针,那么在C#到底该如何安全的调用这样的DLL接口函数呢?本文将详细 ...
- Linux+树莓派3开发总结——树莓派远程文件共享winows
http://blog.csdn.net/xqf1528399071/article/details/52192134 ———————————————————————————————————————— ...
- What exactly can you do with Python? Here are Python’s 3 main applications._你能用Python做什么?下面是Python的3个主要应用程序。
原文链接 Github地址 一.陈述 1,我到底能用Python做什么? 我观察注意到Python三个主要流行的应用: 网站开发: 数据科学——包括机器学习,数据分析和数据可视化: 做脚本语言. 二. ...
- 将Java web应用部署到Tomcat 及部署到Tomcat根目录 的三种方式
Tomcat作为Servlet/JSP容器(服务器)挺不错的,开源免费,需要知道的是Tomcat是一个Web服务器,其符合Servlet/JSP规范,但是却没有实现所有JavaEE规范,所以我们还是应 ...
- [JS] ECMAScript 6 - Set & Map : compare with c#
Ref: Set 和 Map 数据结构 Day 0 - 1所学
- 中文数据解码报错 UnicodeDecodeError: 'gbk' codec can't decode bytes in position 2-3: illegal multibyte sequence
UnicodeDecodeError: 'gbk' codec can't decode bytes in position 2-3: illegal multibyte sequence 失败原因: ...
- ganglia分布式监控部署
一.介绍 Ganglia是由UC Berkeley发起的一个开源监控项目,设计用于监控数以千几的节点.每台服务器都运行一个收集和发送监控数据名为gmond的守护进程.它将从操作系统和指定 ...
- windows 上的 neovim 配置
可以使用简单的 linux 下 neovim 配置,增加了对 golang, python, ruby 脚本文件一键运行快捷方式. """""&qu ...
- nunit2.5.7 单元测试时提示:“当前不会命中断点 还没有为该文档加载任何符号”
解决方案: 因为项目的“目标框架”是.net4.5 所以要将对应的 nunit.exe.config 或 nunit-x86.exe.config 文件中加上: <startup> < ...