引用类型与值

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. GB28181实现摄像头语音对讲 - web音频采集调用示例

    背景分析 近年来,国内视频监控应用发展迅猛,系统接入规模不断扩大,涌现了大量平台提供商,平台提供商的接入协议各不相同,终端制造商需要给每款终端维护提供各种不同平台的软件版本,造成了极大的资源浪费.各地 ...

  2. 深入理解JNI、安全点与循环优化:构建高健壮性Java应用

    来都来了 ~ 先赞后看 效果翻倍哦 ~ 引言 在Java开发者的工具箱中,有一些看似神秘却极其重要的底层概念.你是否曾听说过在循环中插入Thread.sleep(0)可以"唤醒"G ...

  3. PHP SPL SplFileInfo FilterIterator 轮询文件删除

    基于PHP spl 遍历文件删除过期的日志文件 一.定义PHP类 , 限制文件扩展 RecursiveFileFilterIterator.class.php <?php class Recur ...

  4. angluarjs中指令的使用方式

    本人初学者,如有不足虚心求教! angular指令的模块可以分下面几个部分: restrict:用于操作dom的[E]元素,[A]属性,[C]样式,同时也能组合使用 priority:设置当前指令的优 ...

  5. ChCore-lab2

    lab 2: Memory Manage 前言 新的环境好像不支持arm架构了,总是会在make build触发错误(提示镜像仅适配(linux/amd)平台QAQ)......运行make buil ...

  6. ZKEACMS:基于ASP.Net Core开发的开源免费内容管理系统

    前言 哈喽,大家好!我是码农刚子,大家应该都已和床分手,去上班了吧.国庆假期在家没事,试用了一下ZKEACMS,一个可视化拖拽的内容管理系统,今天给大家介绍一下. 简介 ZKEACMS也叫纸壳CMS, ...

  7. 一生一芯学习:PA2:输入输出

    输入输出是计算机与外界交互的基本手段,只需要向设备发送一些有意义的数字信号,设备就会按照这些信号来工作.设备有自己的专属寄存器(如CPU的通用寄存器),也有自己的功能部件(如CPU的ALU).以键盘外 ...

  8. FRP 服务的搭建(内网穿透)

    @charset "UTF-8"; .markdown-body { font-weight: 400; line-height: 2; font-size: 17px; over ...

  9. uni-app x使用uview-plus

    一.概述 ‌uView-Plus官网提供完整框架文档与资源下载‌,是兼容多端开发的uni-app生态框架,支持安卓.iOS.微信小程序等10个平台.   uView-Plus官网及框架概述 ‌官网入口 ...

  10. C++学习笔记(6)

    其他: 省略号作函数参数:表示函数的参数是不固定的,可以传递一个或者多个参数(如:printf函数):void Output(int num, ...) 函数重载:函数的参数个数,类型不同,注意函数的 ...