4.7 属性 属性用于class文件格式中的ClassFile,field_info,method_info和Code_attribute结构. 所有的属性都是下面的格式: attribute_info { u2 attribute_name_index; u4 attribute_length; u1 info[attribute_length]; } 对于所有的属性,attribute_name_index是类文件常量池中有效的16位索引.在这个索引位置的常量池条目必须是CONSTANT_U…
第四章 class文件格式 本章介绍了java虚拟机的class文件格式.每一个class文件包含一个单独的类或者接口的定义.虽然类和接口不一定都定义在文件中(比如类和接口亦可以通过类加载器直接生成),我们将通俗地将类或接口的任何有效表示称为class文件格式.class文件是由8位的字节流组成.所有16位,32位和64位的数字都是分别通过读取两个.四个和八个连续的8位字节来构成.多字节的数据使用大端模式存储的,也就是高字节在前.在java se平台,这个格式由接口java.io.DataInp…
4.7.1 定义和命名新属性 允许编译器定义和发布的class文件在class文件结构体.field_info结构体.method_info结构体和Code结构体中的attributes表中包含新的属性.允许java虚拟机识别和使用attributes表中的新属性.但是,任何没有在class文件规范中定义的属性都不能影响class文件的语义.java虚拟机的实现需要忽略它们不能识别的属性. 例如,允许定义一个新属性来支持特定供应商的调试.因为java虚拟要需要忽略它们不能识别的属性,为特殊jav…
4.5 字段 字段使用field_info结构来描述. 在同一个class文件中的两个字段不能有相同的名称和描述符. 结构的格式如下: field_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count]; } field_info结构中的项目如下: access_flags access_flags的值是…
4.7.5 Exceptions 属性 Exceptions 属性是一个变长属性,它位于 method_info(§4.6)结构的属性表中. Exceptions 属性指出了一个方法需要检查的可能抛出的异常.一个 method_info 结构中最多只能有一个 Exceptions 属性. Exceptions 属性格式如下: Exceptions_attribute { u2 attribute_name_index; u4 attribute_length; u2 number_of_exce…
4.4 常量池 java虚拟机指令并不依赖类.接口.类实例或者数组的运行时布局.相反,指令依靠常量池中的符号信息. 所有的常量池条目都有如下的通用结构: cp_info { u1 tag; u1 info[]; } 常量池表中的每一个项目是以1比特的标识位开始,指示是哪种cp_info条目.info数组的内容由标志位来决定.有效的标识以及对应的值见表4.4-A.每个标识位后面必须跟2个或更多字节,这些字节给出了这些指定常量的信息.额外信息的格式由标识值来决定. 表4.4-A 常量池标识 Cons…
4.7.4 StackMapTable 属性 StackMapTable 属性是一个变长属性,位于 Code(§4.7.3)属性的属性表中.这个属性会在虚拟机类加载的类型阶段(§4.10.1)被使用. StackMapTable 属性包含 0 至多个栈映射帧(Stack Map Frames),每个栈映射帧都显式或隐式地指定了一个字节码偏移量,用于表示局部变量表和操作数栈的验证类型(Verification Types §4.10.1). 类型检测器(Type Checker)会检查和处理目标方…
本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第二章 虚拟机结构 本文档描述了一个抽象的虚拟机规范,并不描述某个特定的虚拟机实现. 要正确实现一个Java虚拟机,你只需要能够读取class文件的格式并正确执行其中指定的操作.具体的实现并不是java虚拟机规范的一部分,因为它们会限制实现者的创造力.比如,运行时数据区域的内存布局,垃圾回收使用的算法,以及任何的java虚拟机指令的内部优化(如:转换为机器码)…
3.12 抛出和处理异常 在程序中使用throw关键字来抛出异常.编译结果很简单. void cantBeZero(int i) throws TestExc { if (i == 0) { throw new TestExc(); } } 编译为: Method void cantBeZero(int) iload_1 // (i) ifne // If i==, allocate instance and throw new # // Create instance of TestExc d…
2.11 指令集简介 java虚拟机指令由一个字节的操作码,接着时0个或多个操作数组成,操作码描述了执行的操作,操作数提供了操作所需的参数或者数据.许多指令没有操作数只包含一个操作码. 如果忽略异常处理,那java虚拟机使用下面的伪代码循环即可有效工作: do{ 自动计算pc然后获取pc中的操作码; if (存在操作数) 获取操作数; 执行这个操作码定义的操作 }while(是否有更多需要执行); 操作数的数量和大小都有操作码决定.如果一个操作数大于一个字节,那么它将以大端顺序存储——高位在前.…
2.5 运行时数据区域 java虚拟机定义了多个用于程序执行期间的运行时数据区域.这些数据区域中一些随着java虚拟机的启动而创建,随着虚拟机的退出而销毁.其他的数据区域时和线程相关的.线程相关数据区域随着线程的创建而创建,随着线程的退出而销毁. 2.5.1 pc寄存器 java虚拟机支持多个线程同时执行.每个线程拥有自己的pc(program counter)寄存器.在任何时刻,一个线程只会执行一个方法,即线程的当前方法.如果执行的方法不是本地(native)方法,pc寄存器包含当前正在执行的…
本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第三章 java虚拟机的编译 java虚拟机是设计用来支持java编程语言的.Oracle的JDK软件包含了一个将Java源代码编译成java虚拟机指令集的编译器,以及一个用于java虚拟机本身的运行时系统.了解编译器如何使用java虚拟机对编译器作者来说是有用的,同样也有助于理解java虚拟机本身.本章中编号的部分不是规范性的. 注意,术语“编译器”有时用于…
2.10 异常 java虚拟机中的异常用Throwable类或者它的子类的实例来表示.抛出一个异常会导致立即非本地(an inmediate nolocal)的控制转移,从发生异常的地方跳到处理异常的地方. 大多数异常是在当前线程执行某些操作时同步发生的.对应的,非同步异常可能发生在程序执行的任何阶段.java虚拟机会由于下面三个原因中的一个抛出异常: 执行athrow指令 java虚拟机同步检测到非正常的执行情况.这些异常不是在程序中的任意点抛出的,而是在执行以下指令后同步抛出: 指明异常作为…
2.7 对象的表示 java虚拟机并不要求对象满足任何特定的内部结构. 在Oracle的一些Java虚拟机实现中,对类实例的引用是指向句柄的指针,该句柄本身是一对指针:一个指向包含对象方法的表和指向表示Class对象的指针对象的类型,另一个是从堆为对象数据分配的内存. 2.8 浮点算法 Java虚拟机包含IEEE二进制浮点运算标准(ANSI / IEEE Std.754-1985,New York)中规定的浮点运算的子集. 2.8.1 Java虚拟机浮点算法和IEEE 754 Java虚拟机支持…
2.6. 栈帧 栈帧用于存储数据和部分结果,同样也用于执行动态链接,返回方法的值和分派异常. 当方法被调用的时候会创建一个新的栈帧.当一个方法调用结束时,它对应的栈帧就被销毁了,不管是正常调用结束还是意外结束(抛出了未被捕获的异常).栈帧分配在线程创建的虚拟机栈中.每个栈帧都有自己的局部变量表,操作数栈,以及当前方法的类的运行时常量池的引用. 可以使用附加的特定于实现的信息来扩展帧,例如调试信息 局部变量表和操作数栈在编译时期就确定了,并且通过栈帧关联的方法的code提供.因此栈帧的大小仅仅取决…
3.6 接受参数 如果n个参数传给一个实例的方法,按照约定,它们被接受并放在这个新方法创建的栈帧中的局部变量表里,在局部变量表中的序号从1到n.这些参数按照它们传递过来的顺序存放.例如: int addTwo(int i, int j) { return i + j; } 编译为 Method int addTwo(int,int) iload_1 // (i) iload_2 // (j) iadd // Add; leave int result on operand stack iretu…
3.3 算术运算 java虚拟机通常在操作数栈上进行算术运算(例外情况是iinc指令,它直接增加一个局部变量的值).例如下面的align2grain()方法,它的作用是将int值对齐到2的指定次幂: int align2grain(int i, int grain) { return ((i + grain-1) & ~(grain-1)); } 算术运算的操作数是从操作数栈中弹出的,运算结果会压回操作数栈.因此,算术子计算的结果可以作为嵌套计算的操作数.例如.~(grain-1)的计算结果就是…
一.Java平台的结构图 二.JVM与JRE.JDK关系? JVM:Java Virtual Machine(Java虚拟机),负责执行符合规范的Class文件 JRE:Java Runtime Environment(java运行环境),包含JVM和类库         JDK:Java  Development Kit(java开发工具包),包含JRE和开发工具包,例如javac.javah 相关文章:http://blog.csdn.net/ljheee/article/details/5…
Java虚拟机规范官方文档    …
前言 java虚拟机是java跨平台的基石,本文的描述以jdk7.0为准,其他版本可能会有一些微调.java代码本身并不能为jvm识别,实际上在jvm中的表现形式为Class对象,一个java类从字节码到能够在jvm中正常运行,需要经过加载->链接->初始化三个步骤. 引用 java虚拟机规范 非法向前引用讨论 虚拟机的启动 java虚拟机的启动是通过引导类加载器(Bootstrap Class Loader)创建一个初始类来完成,这个类是由虚拟机的具体实现指定.紧接着,JAVA虚拟机链接这个…
前言 java虚拟机是java跨平台的基石,本文的描述以jdk7.0为准,其他版本可能会有一些微调. 引用 java虚拟机规范 数据类型 java总共有两种数据类型:基本类型和引用类型.java虚拟机的设计目标是期望在运行前执行类型识别,并且通过编译器识别而不是jvm虚拟机本身.具体的类型如下所示: 基本类型: numeric,如int.float.double等 boolean,实际上boolean类型与int类型在jvm中的处理方式是一样的,也是8bit,true和false分别映射为1和0…
前言 java虚拟机是java跨平台的基石,本文的描述以jdk7.0为准,其他版本可能会有一些微调. 引用 java虚拟机规范 java虚拟机规范-运行时数据区 java内存运行时的栈帧结构 java code to byte code 栈帧 每当一个java方法被执行时都会在虚拟机中新创建一个栈帧,方法调用结束后即被销毁. 栈帧存储空间为虚拟机栈,每一个栈帧都有自己的局部变量表.操作数栈和指向当前方法所属的类的运行时常量池的引用. 在每个线程中,只有目前正在执行的那个方法的栈帧是活动的.这个栈…
1.1 class文件格式 编译后被Java虚拟机所执行的代码使用了一种平台中立的二进制格式来表示,并且经常以文件的形式来存储,这种格式称为class文件格式.class文件格式中精确的定义了类与接口的表示形式. class文件是被java虚拟机所执行的代码. 1.2 数据类型 原始数据类型:数值类型.boolean类型.returnAddress类型. 数值类型:整数类型.浮点类型. 整数类型:byte(8位有符号二进制补码整数,-128(-2^7)- 127(2^7-1)).short(16…
加载(loading):通过一个特定的名字,找到类或接口的二进制表示,并通过这个二进制表示创建一个类或接口的过程. 链接:是获取类或接口并把它结合到JVM的运行时状态中,以让类或接口可以被执行 初始化:初始化一个类或接口——就是执行这个类或接口的<clinit>方法 运行时常量池(在方法区中) 在类或接口C创建的过程中,根据类或接口C的二进制表示中的常量池来创建运行时常量池. 运行时常量池中有许多运行时常量,运行时常量 有的是符号引用,有的不是符号引用 运行时常量池中所有的引用最初都是符号引用…
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 大家知道,我们的Java程序被编译器编译成class文件,在class文件中描述的各种信息,最终都需要加载到虚拟机内存才能运行和使用,那么虚拟机是如何加载这些class文件的呢?在加载class文件的过程中虚拟机又干了哪些事呢?今天我们来解密虚拟机的类加载机制. 虚拟机把class文件加载到内存,并对数据进行校验.解析和初始化,最终形成可以被虚拟机直接使用的Java类型(Class对象),这就是虚拟机的类加载机制. 类从被加载到虚拟机…
上节学习回顾 上一节,我们深入到类文件去了解其结构细节,也大概对类文件的编写规则略知一二了,解析来我们就得学习这个类文件是如何被加载到Java虚拟机的,看看有什么引人入胜的奥秘. 本节学习重点 大部分计算机类科生都应该有接触过C语言,C语言的编译过程会有预处理.编译.汇编.链接四个步骤,经过了这四个步骤就生成了可以执行文件(二进制机器码).Java同样如此, 有Java使用经验的伙伴都应该知道,类加载有加载.连接.初始化三个阶段,这就是虚拟机类加载的三大步骤,只有经过了这三大步骤才能在Java虚…
深入理解Java虚拟机--中 第6章 类文件结构 6.2 无关性的基石 无关性的基石:有许多可以运行在各种不同平台上的虚拟机,这些虚拟机都可以载入和执行同一种平台无关的字节码(ByteCode),从而实现了程序的"一次编写,到处运行". Java语言中的各种变量.关键字和运算符号的语义最终都是由多条字节码命令组合而成的,因此字节码命令所能提供的语义描述能力肯定会比Java语言本身更加强大. 6.3 Class类文件的结构 注意:任何一个Class文件都对应着唯一一个类或接口的定义信息,…
代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 7.1 概述 上一章我们了解了Class文件存储格式的具体细节,在Class文件中描述的各种信息,最终都需要加载到虚拟机中之后才能运行和使用.而虚拟机如何加载这些Class文件?Class文件中的信息进入到虚拟机后会发生什么变化?这些都是本章将要讲解的内容. 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载…
四 虚拟机类加载机制 1 类加载机制     ---概念:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型.     ---Java语言中,类型的加载.连接和初始化过程都是在程序运行期间完成的.     ---类的生命周期包括:加载.验证.准备.解析.初始化.使用.卸载,其中验证.准备.解析统称为连接.     ---加载.验证.准备.初始化和卸载这5个阶段的开始顺序是确定的,但是通常会在一个阶段执行的过程中调用.激活…
目录 7.1 概述 7.2 类加载的时机 类的生命周期 5种情况需要"初始化" 7.3 类加载的过程 1.加载 2.验证 3.准备 4.解析 5.初始化 7.4 类加载器 类与类加载器 类加载器分类 双亲委派模型   7.1 概述 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 类是在运行期间第一次使用时动态加载的,而不是编译时期一次性加载.   7.2 类加载的时机 类的生命周…