深入理解Java虚拟机6-chap8-9-斗者3星
一、虚拟机字节码执行引擎
1.虚拟机执行引擎由自己实现,所以可以自行制定指令集与执行引擎的体系结构,并且可以执行那些不被硬件直接支持的指令集格式。
2.执行引擎
- 编译执行:通过JIT编译器产生本地代码执行
- 解释执行:通过解释器解释执行
二、运行时栈帧结构
- 栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。
- 对于执行引擎来说,在活动线程中,只有位于栈顶的栈帧才是有效的,称为当前栈帧。
1.局部变量表
- 编译时,在方法的Code属性的max_locals确定需要分配的局部变量表的最大容量
- 对于实例方法,局部变量表中的0位索引的Slot默认记录方法所属对象实例的引用,即this指针
- 根据变量作用域,Slot可以被复用,可能对垃圾回收产生影响,如果对变量赋null,在JIT编译中会被清除,最优雅的解决方法是以恰当的变量作用域来控制变量的回收时间
2.操作数栈
- LIFO栈
- 最大深度为编译时写入方法表中Code属性的max_stacks
- 可能会有不同栈间的数据共享
3.动态连接
- 每个栈帧都包含一个指向运行时常量池中该栈帧所属性方法的引用,用来支持动态连接
- 字节码中的方法调用指令:以常量池中指向方法的符号引用为参数
- 符号引用解析:一部分发生在类加载或者第一次使用,即静态解析,动态解析发生在每一次运行期
4.方法返回地址
- 正常完成出口
- 异常完成出口
5.附加信息
- 在实际开发中,一般会把动态连接,方法返回地址与其它附加信息全部归为一类,称为栈帧信息。
三、方法调用
- 目的:确定调用方法的版本
- 一切方法调用在Class文件里存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址(相当于直接引用)
1.解析
- 类加载的解析阶段,会把其中一部分符号引用转化为直接引用,前提:方法在程序运行之前只有一个可确定的调用版本,并且这个调用版本在运行期不可变
- 编译器可知,运行期不可变:静态方法与私有方法,
- 五条方法调用字节码指令
1)invokestatic:调用静态方法
2)invokespecial:调用实例构造器方法,私有方法和父类方法。
3)invokevirtual:调用虚方法。
4)invokeinterface:调用接口方法,会在运行时再确定一个实现此接口的对象。
5)invokedynamic:先在运行时动态解析出调用点限定符所引用的方法,然后再执行该方法,在此之前的4条调用指令,分派逻辑是固化在Java虚拟机内部的,而invokedynamic指令的分派逻辑是由用户所设定的引导方法决定的。
- 只要能被invokestatic与invokespecial指令调用的方法,都可以在解析阶段确定唯一的调用版本,符合这个条件的有静态方法,私有方法,实例构造器和父类方法四类,它们在类加载的时候就会把符号引用解析为该方法的直接引用。这些方法可以统称为非虚方法,与之相反,其它方法就称为虚方法(除去final方法)。
- final方法虽然由invokevirtual调用,但是由于它无法被覆盖,没有其他版本,所以也是非虚方法
2.分派
- 静态分派:依赖静态类型来定位方法执行版本的分派动作称为静态分派,典型应用为方法重载
1)Shape s = new Circle(),Shape称为静态类型,Circle称为实际类型
- 动态分派:依赖动态类型执行方法分派,典型应用为重写
1)动态分派时,会根据当前栈帧的局部变量表,进行挨个遍历匹配接受者(即调用者),由于invokevirtual指令执行的第一步就是在运行期确定接受者的实际类型,这个过程就是Java语言重写的本质
- 单分派与多分派
1)方法的接受者与方法的参数称为方法的宗量。
2)单分派是根据一个宗亮对目标方法进行选择,多分派是根据多个宗量
3)Java语言:静态多分派、动态单分派
4)动态分派,优化手段:虚方法表,若方法没被重写,则地址入口与父类相同方法地址一致
3.动态语言支持
- 反射与invokedynamic指令
四、基于栈的字节码解释执行引擎
1.解释执行
- Java 语言中, Javac 编译器完成了程序代码经过词法分析、语法分析到抽象语法树,再遍历语法树生成线性的字节码指令流的过程
- 解释器在JVM内部,所以Java程序的编译是半独立的实现
- 中间过程:解释执行
- 下面过程:传统编译原理程序代码到目标机器代码的生成过程
2.基于栈指令集与寄存器指令集
- 基于栈的指令集主要的优点就是可移植,寄存器由硬件直接提供,程序直接依赖这些硬件寄存器则不可避免地要受到硬件的约束。
- 栈架构指令集的主要缺点是执行速度相对来说会稍慢一些。
- 虽然栈架构指令集的代码非常紧凑,但是完成相同功能所需的指令数量一般会比寄存器架构多,因为出栈、入栈操作本身就产生了相当多的指令数量,,栈实现在内存之中,频繁的栈访问也就意味着频繁的内存访问,相对于处理器来说,内存始终是执行速度的瓶颈。
五、类加载器
1.Tomcat
2.OSGI:运行时生成类加载体系结构
3.字节码生成与动态代理技术
4.Restrotranslator:Java逆向移植工具
- 基本原理是将新特性在编译时进行替换,如包装对象,更换为Integer.valueOf()
参考:
https://gavinzhang1.gitbooks.io/java-jvm-us/content/xu_ni_ji_zi_jie_ma_zhi_xing_yin_qing.html
深入理解Java虚拟机6-chap8-9-斗者3星的更多相关文章
- 《深入理解Java虚拟机》虚拟机性能监控与故障处理工具
上节学习回顾 从课本章节划分,<垃圾收集器>和<内存分配策略>这两篇随笔同属一章节,主要是从理论+实验的手段来讲解JVM的内存处理机制.好让我们对JVM运行机制有一个良好的概念 ...
- 《深入理解 java虚拟机》学习笔记
java内存区域详解 以下内容参考自<深入理解 java虚拟机 JVM高级特性与最佳实践>,其中图片大多取自网络与本书,以供学习和参考.
- (1) 深入理解Java虚拟机到底是什么?
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/20380971 什么是Java虚拟机 作为一个Java程序员,我们每天都在写Java ...
- 深入理解java虚拟机(7)---线程安全 & 锁优化
关于线程安全的话题,足可以使用一本书来讲解这些东西.<Java Concurrency in Practice> 就是讲解这些的,在这里 主要还是分析JVM中关于线程安全这块的内容. 1. ...
- 深入理解java虚拟机(6)---内存模型与线程 & Volatile
其实关于线程的使用,之前已经写过博客讲解过这部分的内容: http://www.cnblogs.com/deman/category/621531.html JVM里面关于多线程的部分,主要是多线程是 ...
- 深入理解java虚拟机(5)---字节码执行引擎
字节码是什么东西? 以下是百度的解释: 字节码(Byte-code)是一种包含执行程序.由一序列 op 代码/数据对组成的二进制文件.字节码是一种中间码,它比机器码更抽象. 它经常被看作是包含一个执行 ...
- 深入理解java虚拟机(4)---类加载机制
类加载的过程包括: 加载class到内存,数据校验,转换和解析,初始化,使用using和卸载unloading过程. 除了解析阶段,其他过程的顺序是固定的.解析可以放在初始化之后,目的就是为了支持动态 ...
- 深入理解java虚拟机(1)------内存区域与内存溢出
在C++领域,关于C++的内存存储,结构等等,有一本书:深度探索C++对象模型,讲解的非常透彻. 而Java确把这一工作交给了虚拟机来处理. 我们首先来看看关于内存的问题. 1.问题: 1)java ...
- 什么是HotSpot VM & 深入理解Java虚拟机
参考 http://book.2cto.com/201306/25434.html 另外,这篇文章也是从一个系列中得出的: <深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)> ...
- 【Todo】深入理解Java虚拟机 读书笔记
有一个在线系列地址 <深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)> http://book.2cto.com/201306/25426.html 已经下载了这本书(60多M ...
随机推荐
- Caffe 分类问题 Check failed: error == cudaSuccess (2 vs. 0) out of memory
如果图片过大,需要适当缩小batch_size的值,否则使用GPU时可能超出其缓存大小而报错
- github控件地址
地址: https://github.com/wasabeef/awesome-android-ui http://www.jcodecraeer.com/plus/list.php?tid=31 h ...
- ViZDoom深度预测(Depth Prediction)
代码:github.com/huangshiyu13/ViZDoomDepth 图片被分成3x6的区域,利用模型预测每个区域的平均深度,效果如下图:
- Android 8 设置蓝牙名称 流程
记录android 8设置蓝牙名称的流程. packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothDeviceRenam ...
- k8s的使用
. 查看 kubectl 的状态 kubectl version . 查看集群信息 kubectl cluster-info . 查看节点信息 kubectl get nodes . 创建一个发布 k ...
- Elasticsearch学习笔记——常用命令
1.创建一个名字为index的topic curl -XPUT http://localhost:9200/index 2.创建一个mapping curl -XPOST http://localho ...
- MySQL-[SIGNAL/RESIGNAL/GET DIAGNOSTICS]的使用
最近在做 SQL Server 到 MySQL 的迁移(migration),相较于对表和数据的迁移,最令人犯难的还是在功能性存储过程脚本的改写转换(convert),虽说 MySQL 如今是蓬勃发展 ...
- python基础类型—数字(Number)
Python3 支持 int.float.bool.complex(复数). 在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long. 像大多数语言一样,数 ...
- QT下的贪吃蛇
QT写的贪吃蛇,学习于https://www.devbean.net/2012/12/qt-study-road-2-snake-1/ 建议就学习一下开发思想,开发游戏还是用专门的编译器. 多加了墙, ...
- react ref获取dom对象
react文档 step = React.createRef(); // init <div ref={this.step}></div> // bind componentD ...