引用类型与值

Java虚拟机中有三种引用类型:类类型(Class Types)、数组类型(Array Types)和接口类型(Interface Types)。这些引用类型的值分别由类实例、数组实例和实现了某个接口的类实例或数组实例动态创建。

异常

Java虚拟机中异常的出现总是由下面三种原因之一导致的:
1. 虚拟机同步检测到程序发生了非正常的执行情况,这时异常将会紧接着在发生非正常执行情况的字节码指令之后抛出。例如:

 字节码指令所蕴含的操作违反了Java语言的语义,如访问一个超出数组边界范围的元素。
 类在加载或者链接时出现错误。
 使用某些资源的时候产生资源限制,例如使用了太多的内存。

2. athrow字节码指令被执行。
3. 由于以下原因,导致了异步异常的出现:
 调用了Thread或者ThreadGroup的stop方法。
 Java虚拟机实现的内部程序错误。
当某条线程调用了stop方法时,将会影响到其他的线程,或者在线程组中的所有线程。这时候其他线程中出现的异常就是异步异常,因为这些异常可能出现在程序执行过程的任何位置。虚拟机的内部异常也被认为是一种异步异常

字节码指令集

字节码指令流应当都是单字节对齐的,只有“tableswitch”和“lookupswitch”两条指令例外,由于它们的操作数比较特殊,都是以4字节为界划分开的,所以这两条指令那个也需要预留出相应的空位来实现对齐。

限制Java虚拟机操作码的长度为一个字节,并且放弃了编译后代码的参数长度对齐,是为了尽可能地获得短小精干的编译代码,即使这可能会让Java虚拟机的具体实现付出一定的性能成本为代价。由于每个操作码只能有一个字节长度,所以直接限制了整个指令集的数量,又由于没有假设数据是对齐好的,这就意味着虚拟机处理那些超过一个字节的数据的时候,不得不在运行时从字节中重建出具体数据的结构,这在某种程度上会损失一些性能。字节码无法超过256条的限制就来源于此。

数据类型与Java虚拟机

Java虚拟机的指令集对于特定的操作只提供了有限的类型相关指令去支持它,换句话说,指令集将会故意被设计成非完全独立的(Not Orthogonal,即并非每种数据类型和每一种操作都有对应的指令)。有一些单独的指令可以在必要的时候用来将一些不支持的类型转换为可被支持的类型。

大部分的指令都没有支持整数类型byte、char和short,甚至没有任何指令支持boolean类型。编译器会在编译期或运行期会将byte和short类型的数据带符号扩展(Sign-Extend)为相应的int类型数据,将boolean和char类型数据零位扩展(Zero-Extend)为相应的int类型数据。

因此,大多数对于boolean、byte、short和char类型数据的操作,实际上都是使用相应的对int类型作为运算类型(Computational Type)。

同步

Java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步,这两种同步结构都是使用管程(Monitor)来支持的。当方法调用时,调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置,如果设置了,执行线程将先持有管程,然后再执行方法,最后再方法完成(无论是正常完成还是非正常完成)时释放管程。在方法执行期间,执行线程持有了管程,其他任何线程都无法再获得同一个管程。如果一个同步方法执行期间抛出了异常,并且在方法内部无法处理此异常,那这个同步方法所持有的管程将在异常抛到同步方法之外时自动释放。

结构化锁定(Structured Locking)是指在方法调用期间每一个管程退出都与前面的管程进入相匹配的情形。因为无法保证所有提交给Java虚拟机执行的代码都满足结构化锁定,所以Java虚拟机允许(但不强制要求)通过以下两条规则来保证结构化锁定成立。假设T代表一条线程,M代表一个管程的话:
1. T在方法执行时持有管程M的次数必须与T在方法完成(包括正常和非正常完成)时释放管程M的次数相等。
2. 找方法调用过程中,任何时刻都不会出现线程T释放管程M的次数比T持有管程M次数多的情况。
请注意,在同步方法调用时自动持有和释放管程的过程也被认为是在方法调用期间发生。

公有设计,私有实现

实现者可以使用这种伸缩性来让Java虚拟机获得更高的性能、更低的内存消耗或者更好的可移植性,选择哪种特性取决于Java虚拟机实现的目标和关注点是什么,虚拟机实现的方式主要有以下两种:

 将输入的Java虚拟机代码在加载时或执行时翻译成另外一种虚拟机的指令集
 将输入的Java虚拟机代码在加载时或执行时翻译成宿主机CPU的本地指令集(有时候被称Just-In-Time代码生成或JIT代码生成)
精确定义的虚拟机和目标文件格式不应当对虚拟机实现者的创造性产生太多的限制,Java虚拟机是被设计成可以允许有众多不同的实现,并且各种实现可以在保持兼容性的同时提供不同的新的、有趣的解决方案。

加载是根据特定名称查找类或接口类型的二进制表示(Binary Representation),并由此二进制表示创建类或接口的过程。

链接是为了让类或接口可以被Java虚拟机执行,而将类或接口并入虚拟机运行时状态的过程。

虚拟机启动

Java虚拟机的启动是通过引导类加载器(Bootstrap Class Loader §5.3.1)创建一个初始类(Initial Class)来完成,这个类是由虚拟机的具体实现指定。紧接着,Java虚拟机链接这个初始类,初始化并调用它的public void main(String[])方法。之后的整个执行过程都是由对此方法的调用开始。执行main方法中的Java虚拟机指令可能会导致Java虚拟机链接另外的一些类或接口,也可能会调用另外的方法。

创建和加载

Java虚拟机支持两种类加载器:Java虚拟机提供的引导类加载器(Bootstrap Class Loader)和用户自定义类加载器(User-Defined Class Loader)。每个用户自定义的类加载器应该是抽象类ClassLoader的某个子类的实例。应用程序使用用户自定义类加载器是为了便于扩展Java虚拟机的功能,支持动态加载并创建类。

Java虚拟机规范(JavaSE7) 笔记的更多相关文章

  1. java虚拟机规范学习笔记之数据类型

    1.1 class文件格式 编译后被Java虚拟机所执行的代码使用了一种平台中立的二进制格式来表示,并且经常以文件的形式来存储,这种格式称为class文件格式.class文件格式中精确的定义了类与接口 ...

  2. 《深入理解Java虚拟机》学习笔记之类加载

    之前在学习ASM时做了一篇笔记<Java字节码操纵框架ASM小试>,笔记里对类文件结构做了简介,这里我们来回顾一下. Class类文件结构 在Java发展之初设计者们发布规范文档时就刻意把 ...

  3. 《深入理解Java虚拟机》学习笔记

    <深入理解Java虚拟机>学习笔记 一.走近Java JDK(Java Development Kit):包含Java程序设计语言,Java虚拟机,JavaAPI,是用于支持 Java 程 ...

  4. 深入理解Java虚拟机一 阅读笔记

    xl_echo编辑整理.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!! --- > 以下内容摘抄自 ...

  5. 《深入理解 Java 虚拟机》学习笔记 -- 内存区域

    <深入理解 Java 虚拟机>学习笔记 -- 内存区域 运行时数据区域 主要分为 6 部分: 程序计数器 虚拟机栈 本地方法栈 Java 堆 方法区 如图所示: 1. 程序计数器(线程私有 ...

  6. 深入理解Java虚拟机之读书笔记一 自动内存管理机制

    一.运行时数据区域 1.程序计数器是线程的私有空间,每个线程都有.针对线程执行的是Java代码还是Native代码有两种取值,Java代码时:虚拟机字节码指令的地址:Native代码时:计数值为Und ...

  7. (转)《深入理解java虚拟机》学习笔记7——Java虚拟机类生命周期

    C/C++等纯编译语言从源码到最终执行一般要经历:编译.连接和运行三个阶段,连接是在编译期间完成,而java在编译期间仅仅是将源码编译为Java虚拟机可以识别的字节码Class类文件,Java虚拟机对 ...

  8. (转)《深入理解java虚拟机》学习笔记6——类加载机制

    Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 在加载阶段,java虚拟机需要完成以下 ...

  9. (转)《深入理解java虚拟机》学习笔记3——垃圾回收算法

    Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构 ...

  10. (转)《深入理解java虚拟机》学习笔记1——Java内存结构

    java虚拟机规范规定的java虚拟机内存其实就是java虚拟机运行时数据区,其架构如下: 其中方法区和堆是由所有线程共享的数据区. Java虚拟机栈,本地方法栈和程序计数器是线程隔离的数据区. (1 ...

随机推荐

  1. gem5 CPU ISA level is lower than required

    错误提示: /lib/x86_64-linux-gnu/libc.so.6: CPU ISA level is lower than required 错误截图: 在互联网上搜索该错误,在 gem5 ...

  2. 【学习】重学Swift5-运算符&流程控制

    二.运算符和表达式 + - * \ = // 溢出 &+ &- &* // 合并空值运算符 a??b // a必须是一个可选类型.b必须与a的储存类型相同 与(a = nil ...

  3. 剑指offer-18、⼆叉树的镜像

    题⽬描述 操作给定的⼆叉树,将其变换为源⼆叉树的镜像. ⼆叉树的镜像定义:源⼆叉树 思路及解答 递归 采用后序遍历(左-右-根)的方式递归访问每个节点: 递归处理左子树 递归处理右子树 访问根节点并交 ...

  4. 从 “盲调” 到 “精准优化”:SQL Server 表统计信息实战指南

    本文核心要旨在于:SQL Server 表统计信息作为元数据对象,宛如数据分布的 "指南针",精准存储着数据分布信息,为查询优化器提供关键依据,助力其生成高效的查询执行计划.在维护 ...

  5. Golang URL query contains semicolon 报错解决方案

    ​ 报错信息 http: URL query contains semicolon, which is no longer a supported separator; parts of the qu ...

  6. RoboMaster电控入门(3)RM系列电机控制

    RM系列电机,电调介绍 Robomaster官方提供了一系列性能各异,可以用于不同场景,且易于驱动的直流无刷减速电机及配套电调,这里主要介绍三款常用的电机&电调--M3508电机&C6 ...

  7. DNA 损伤、scRNA-seq 以及 scHiC 数据间的关联

    你问的scHi-C.scRNA.DNA损伤这三者主要是单细胞多组学领域常见的三种分析/表征内容,它们分别指: scHi-C(single-cell Hi-C):单细胞水平的染色质高级结构(染色质空间互 ...

  8. 【光照】UnityURP中的[HDR贴图]

    [从UnityURP开始探索游戏渲染]专栏-直达 HDR贴图的概念与特性 HDR(高动态范围)贴图是Unity URP中用于存储超出标准0-1范围光照信息的特殊纹理格式.与普通LDR(低动态范围)贴图 ...

  9. 权威调研榜单:道路玉兰灯厂家TOP3榜单好评深度解析

    在城市道路照明领域,玉兰灯凭借其优雅的设计和高效的照明性能,成为市政工程和景观亮化的热门选择.随着市场需求的增长,众多厂家竞相涌现,但产品质量.技术实力和服务水平参差不齐.为帮助用户精准筛选优质供应商 ...

  10. KAL1 LINUX 官方文档之介绍 --- ka1i卧底

    ka1i卧底 Kali Undercover是一套脚本,它可以将你的Kali Linux桌面环境的外观和感觉改变为Windows 10桌面环境,像魔术一样. 它是与Kali Linux 2019.4一 ...