JVMS Specification(1)-TheStructure of the Java Virtual Matchine

来源:互联网 发布:网络空间的安全挑战有 编辑:程序博客网 时间:2024/06/05 23:57

Subsections

1      TheStructure of the Java Virtual Matchine

1.1       Theclass File Format

1.2       DataType

1.3       PrimitiveTypes and Values

1.3.1        The numerictypes

1.3.2        The returnAddress Type and Values

1.3.3        The boolean Type

1.4       Reference Types and Values

1.5       Runtime Data Areas

1.5.1        The pc Register

1.5.2        Java Virtual Machine Stacks

1.5.3        Heap

1.5.4        Method Area

1.5.5        Runtime Constant Pool

1.5.6        Native Method Stacks

1.6       Frames

1.6.1        Local Variables

1.6.2        Operand Stacks

1.6.3        Dynamic Linking

1.6.4        Normal Method Invocation Completion

1.6.5        Abrupt Method Invocation Completion

1.7       Representation of Objects

1.8       Floating-Point Arithmetic

1.8.1        Java Virtual Machine Floating-Point Arithmetic and IEEE 754

1.8.2        Floating-Point Modes

1.8.3        Value Set Conversion

1.9       Special Methods

1.10     Exceptions

1.11     InstructionSet Summary

1.11.1      Types and the Java Virtual Machine

1.11.2      Load and Store Instructions

1.11.3      Arithmetic Instructions

1.11.4      Type Conversion Instructions

1.11.5      Object Creation and Manipulation

1.11.6      Operand Stack Management Instructions

1.11.7      Control Transfer Instructions

1.11.8      Method Invocation and Return Instructions

1.11.9      Throwing Exceptions

1.11.1      Synchronization

1.12     ClassLibraries

1.13     PublicDesign, Private Implementation

1      The Structureof the Java Virtual Matchine

Toimplement the java virtual machine correctly, you need only be able to read theClass file format and corrently perform operations specifiedtherein.Implementation details that are not part of the Java virtualmachine'specification would unnecessarily constrain the creativity ofimplementors.For example,the memory layout of runtime data areas,thegarbage-collection algorithm used,and any internal optimization of the javavirtual machine instructions(for example,translating them into machine code)are left to the discretion of the implementor.
要实现正确的java虚拟机,你只需要读到正确的Class格式的文件然后在里面正确的执行指令,具体的实现不包括在java虚拟机规范里,这样会限制实现者的创造能力。比如内存布局的运行时数据区域,垃圾回收器的使用,和java虚拟机内部指令的优化(如,转换它们为机器代码)留给实现者自己去判断。

1.1    The class File Format

Compiled code to be executed by the javavirtual machine is represented using a hardware and operationgsystem-independent binary format,typically(but not necessarily) stored ina file,known as the class file format.The class file format precisely definesthe representation of a class or interface,including details such as byteordering that might be taken for granted in aplatform-specific object fileformat.

编译完被java虚拟机执行的代码是硬件和操作系统独立使用的二进制格式。一般来说,(但不是必须的)存储成一个class文件,这个class文件精确的描述了这个类或者接口,包括详细信息,比如字节顺序可能会被视为一个特定于平台的对象文件格式。

1.2    Data Type

Like the java programminglanguage,the java virtual machine operates on two kind s of types:primitivetypes and reference types.There are correspondingly,two kinds of values thatcan be stored in variables,passed as arguments,returned by method,and operatedupon:primitive values andpreference valuesThe java virtual machine expects that nearly all type checkingis done prior to runtime,typically by compiler,and does not have to be done bythe java virtual machine itself.Vales of primitive type nedd not be tagged orotherwise be inspectable to  determine their types at runtime, or to bedistinguished fromvalues of reference types. Instead, the instruction set ofthe Java virtual machinedistinguishes its operand types using instructionsintended to operate on values of specific types. For instance,  iadd, ladd,  fadd, and  dadd are all Java virtual machineinstructions that add two numeric values and produce numeric results,but eachis specialized  for its operand type:  int,  long,  float,and  double,respectively. For a summary of type support in the Java virtualmachine instruc-tion set. 
The Java virtual machine contains explicitsupport for objects. An object is either a dynamically allocated class instanceor an array. A reference to an object is considered to have Java virtualmachine type reference. Values oftype reference can be thought of as pointersto objects. More than one refer-ence to an object may exist. Objects are alwaysoperated on, passed, and tested via values of type 
就像Java编程语言,java虚拟机两种类型起作用:基本数据类型和引用数据类型。相对应的两种值被存储在变量里面,通过方法的参数或者返回值来操作。java虚拟机希望所有的类型在运行之前被检查,一般是被编译器,并且不需要Java虚拟机自己去做。基本数据类型的值不需要被标记,在运行时他们的类型会被检查,还和引用类型做区分。反而Java虚拟机的指令集区分操作数类型使用指令操作特定类型的值。比如iadd,ladd,fadd,and dadd 这些都是Java虚拟机指令对两个数字值相加,得到的结果是一个数字,但是特定操作数类型之间比如int long float double 之间又是相互独立的。

java虚拟机明确包含支持对象,一个对象是一个类的实例或者是一个数组,一个对象的引用被看作是java虚拟机类型引用,类型引用的值被认为是指针指向的对象,一个对象可能存在多个引用,对象总是被引用操作,传递,或者测试。

1.3    Primitive Types andValues 

基本数据类型以及取值

The primitive data typessupported by the Java virtual machine are thenumeric

types, the boolean type (§2.3.4),1 and the returnAddress type(§2.3.3). The

numeric types consist ofthe integral types (§2.3.1) and the floating-point types

(§2.3.2). The integraltypes are:

• byte, whose values are8-bit signed two’s-complement integers, and whose

default value is zero

• short, whose values are16-bit signed two’s-complement integers, and whose

default value is zero

• int, whose values are32-bit signed two’s-complement integers, and whose

default value is zero

• long, whose values are64-bit signed two’s-complement integers, and whose

default value is zero

• char, whose values are16-bit unsigned integers representing Unicode code

points in the Basic Multilingual Plane, encoded with UTF-16, and whose

default value is the null code point ('\u0000')

The floating-point types are:

• float, whose values areelements of the float value set or, where supported,

the float-extended-exponent value set, and whose default value is positivezero

• double, whose values areelements of the double value set or, where supported,

the double-extended-exponent value set, and whose default value is positivezero

The values of the boolean type encode the truth values true and false, and the defaultvalue is false.

The values of the returnAddress type are pointers to the opcodes of Java

virtual machine instructions. Of the primitive types only the returnAddress type is not directlyassociated with a Java programming language type.

译:被java虚拟机支持的基本数据类型有1、数值类型,2、布尔类型和3、返回地址类型

数值类型包括整数型和浮点类型

七个整数型

Byte 一个byte占8个bit,默认为0

Short 一个short占16个bit,默认为0

Int   一个int占32个bit,默认为0

Long  一个long占64个bit,默认为0

Char  其值是表示Unicode代码的16位无符号整数。默认是’\U0000’。

1.3.1  The numerictypes

1.3.1.1             Integral Types and Values

The values of the integral types of the Java virtual machine are:

• For byte, from −128 to 127 (−27 to 27−1), inclusive

取值范围:[-128,127]

• For short, from −32768 to 32767 (−215 to 215−1), inclusive

取值范围:[−32768, 32767]

• For int, from −2147483648 to 2147483647 (−231 to 231−1), inclusive

取值范围:[−2147483648, 2147483647]

• For long, from −9223372036854775808 to 9223372036854775807(−263to 263−1), inclusive

取值范围:[−9223372036854775808, 9223372036854775807]

• For char, from 0 to 65535inclusive

取值范围:[0, 65535]

1.3.1.2             Floating-PointTypes, Value Sets, and Values

The floating-point types are float and double, which areconceptually associated

with the 32-bit single-precision and 64-bit double-precision format IEEE754 values

and operations as specified in IEEE Standard for BinaryFloating-Point Arithmetic,

ANSI/IEEE Std. 754-1985 (IEEE, New York).

The IEEE 754 standard includes not only positive and negativesign-magnitude

numbers, but also positive and negative zeros, positive and negativeinfinities,

and a special Not-a-Number value(hereafter abbreviated as “NaN”). The

NaN value is used to represent the result of certain invalid operationssuch as

dividing zero by zero.

浮点数类型包括float类型和double类型。对应32位单精度和64位双精度IEEE 754格式的值。IEEE标准二进制浮点算术

IEEE 754标准不仅包括正面和负面的有符号数据,而且能表示正,负零,正,负无穷大

和一个特殊的非数字数的值(以下简称为“非数字”)。该 NaN值用于表示某些无效操作,如结果 零被零除。

补充:有符号数的表示需要将负数编码为二进制形式。

二进制      有符号   无符号

01111111     127        127

10000000     −0          128

10000001     −1          129

Every implementation of the Java virtual machine is required to supporttwo

standard sets of floating-point values, called thefloat valuesetand thedouble

value set. In addition, an implementation of the Java virtualmachine may, at its

option, support either or both of two extended-exponent floating-pointvalue sets,

called the float-extended-exponent value setand thedouble-extended-exponent

value set. These extended-exponent value sets may, under certaincircumstances,

be used instead of the standard value sets to represent the values of typefloat or

double.

任何一个JVM的实现必须要求支持两个标准的浮点数集,float和double。此外,有些JVM还包括了延伸单精确度和延伸双精确度集.这些延伸的精度集,只是在特定的情况下替代标准的集而不代表float和double.

The finite nonzero values of any floating-point value set can all beexpressed

in the form s ⋅ m ⋅ 2(eN +1), where s is +1 or −1, m is a positive integer less than

2N, and e is an integer betweenEmin= − (2K− 1 − 2) and Emax = 2K − 1 − 1, inclusive,

and where N and K are parameters that depend on the value set. Some values

can be represented in this form in more than one way; for example,supposing that

a value v in a value set might be represented in this form usingcertain values fors,

m, and e, then if it happened thatmwere even ande were less than 2K − 1, one

could halve m and increaseeby 1 to produce a second representation for the same

value v. A representation inthis form is callednormalizedifm ≥ 2N − 1; otherwise

the representation is said to bedenormalized. If a value in avalue set cannot be

represented in such a way that m ≥ 2N − 1, then the value issaid to be a denormalized

value, because it has no normalized representation.

The constraints on the parametersNandK (and on the derived parameters

Emin and Emax) for the two required and two optional floating-pointvalue sets are

summarized in Table 2.1.

Where one or both extended-exponent value sets are supported by animplementation,

then for each supported extended-exponent value set there is a specific

implementation-dependent constantK, whose value is constrained by Table 2.1;

this value K in turn dictates the values forEminandEmax.

Each of the four value sets includes not only the finite nonzero valuesthat are

ascribed to it above, but also the five values positive zero, negativezero, positive

infinity, negative infinity, and NaN.

Note that the constraints in Table 2.1 are designed so that every elementof the

float value set is necessarily also an element of thefloat-extended-exponent value

set, the double value set, and the double-extended-exponent value set.Likewise,

each element of the double value set is necessarily also an element of thedouble-

extended-exponent value set. Each extended-exponent value set has a larger

range of exponent values than the corresponding standard value set, butdoes not

have more precision.

The elements of the float value set are exactly the values that can berepresented

using the single floating-point format defined in the IEEE 754 standard,

except that there is only one NaN value (IEEE 754 specifies 224 − 2 distinct NaN

values). The elements of the double value set are exactly the values thatcan be

represented using the double floating-point format defined in the IEEE 754standard,

except that there is only one NaN value (IEEE 754 specifies 253 − 2 distinct

NaN values). Note, however, that the elements of thefloat-extended-exponent and

double-extended-exponent value sets defined here donotcorrespond to thevalues

that be represented using IEEE 754 single extended and double extendedformats,

respectively. This specification does not mandate a specificrepresentation for the

values of the floating-point value sets except where floating-point valuesmust be

represented in the class file format (§4.4.4, §4.4.5).

The float, float-extended-exponent, double, and double-extended-exponent

value sets are not types. It is always correct for an implementation ofthe Java virtual

machine to use an element of the float value set to represent a value oftype

float; however, it may be permissible in certain contexts foran implementation

to use an element of the float-extended-exponent value set instead.Similarly, it is

always correct for an implementation to use an element of the double valueset to

represent a value of type double; however, it may be permissible in certain con-

Table 2.1 Floating-point value set parameters

Parameter float

float-extendedexponent

double

double-extendedexponent

N 24 24 53 53

K 8 ≥ 11 11 ≥ 15

Emax +127 ≥ +1023 +1023 ≥ +16383

Emin −126 ≤ −1022 −1022 ≤ −16382

THE STRUCTURE O 10 F THE JAVA VIRTUAL MACHINE

texts for an implementation to use an element of thedouble-extended-exponent

value set instead.

Except for NaNs, values of the floating-point value sets areordered. When

arranged from smallest to largest, they are negative infinity, negativefinite values,

positive and negative zero, positive finite values, and positive infinity.

Floating-point positive zero and floating-point negative zero compare as

equal, but there are other operations that can distinguish them; forexample, dividing

1.0 by 0.0 produces positive infinity, but dividing 1.0 by -0.0 produces

negative infinity.

NaNs are unordered, so numerical comparisons and tests for numericalequality

have the value false if either or both of their operands are NaN. Inparticular,

a test for numerical equality of a value against itself has the value false if and

only if the value is NaN. A test for numerical inequality has the value true if

either operand is NaN.

NaN值是无序的,所以如果两个操作是都是NaN或者其中一个操作数是NaN,那么比较或者测试两个值是否相等将返回false。特别的,其中一个操作数为NaN那么测试不相等将返回true。

1.3.2     The returnAddress Type and Values

The returnAddress type is used by theJava virtual machine’sjsr,ret, andjsr_w

instructions. The values of the returnAddress type are pointers tothe opcodes

of Java virtual machine instructions. Unlike the numeric primitive types,the

returnAddress type does not correspond to any Java programming language

type and cannot be modified by the running program.

返回类型被jsr,ret ,jsr_w使用,它的值是JVM指令的操作码的指针,不同于数值类型,它不对应于任何Java编程语言型并且它的值是不能被运行中的程序所修改的。

 

1.3.3     The boolean Type

Although the Java virtual machine defines a boolean type, it only providesvery

limited support for it. There are no Java virtual machine instructionssolely dedicated

to operations on boolean values. Instead, expressions in the Java programming

language that operate on boolean values are compiled to use values of the

Java virtual machine int data type.

The Java virtual machine does directly support boolean arrays. Itsnewarray

instruction enables creation of boolean arrays. Arrays of type boolean are

accessed and modified using the byte array instructionsbaloadandbastore.2

The Java virtual machine encodes boolean array components using1to represent

true and 0 to represent false. Where Java programming language boolean

values are mapped by compilers to values of Java virtual machine type int, the

compilers must use the same encoding.

尽管JVM定义了布尔类型,但是其能提供的支持非常有限。他们没有专门独自的JVM指令提供给布尔类型来操作。而是, java程序中表示操作布尔类型的值被编译使用JVM整数类型。

JVM不直接支持布尔数组,它的新指令能使用创建了的布尔数组。布尔类型的数组使用byte数组指令来访问和修改。JVM使用1表示真,0表示假来对布尔数组进行编码。无论怎样,java编程语言布尔类型的值都会被编译器映射为jvm 整数类型的值

1.4     Reference Types and Values

There are three kinds of reference types: class types, array types, and interface

types. Their values are references to dynamically created class instances,arrays, or

class instances or arrays that implement interfaces, respectively.

An array type consists of a component type with a single dimension (whose

length is not given by the type). The component type of an array type mayitself be

an array type. If, starting from any array type, one considers itscomponent type,

and then (if that is also an array type) the component type of that type,and so on,

eventually one must reach a component type that is not an array type; thisis called

the element typeof the array type. Theelement type of an array type is necessarily

either a primitive type, or a class type, or an interface type.

A reference value may also be thespecial null reference, a reference to no

object, which will be denoted here by null. The null reference initiallyhas no

runtime type, but may be cast to any type. The default value of areference type is

null.

The Java virtual machine specification does not mandate a concrete value

encoding null.

三种不同类型的引用类型:类类型,数组类型,接口类型。它们的值被类实例和数组或者实现了接口的类实例和数组动态创建。个别的(respectively),数组类型又组件类型组成(长度没有通过类型给出)。这个数组类型的组件类型,可能自己本身就是一个数组类型,数组类型的组件类型本身可以是 数组类型。如果,从任何数组类型开始,人们认为其组件类型, 然后(如果这也是一个数组类型),该类型的组件类型,等等, 最终必须达成一个组件类型不是数组类型;称之为数组类型的元素类型,数组类型的元素类型必须是基本数据类型,或者类类型,或者接口类型。

一个引用类型的值可能是个空引用,这个引用没有指向任何对象,表示(denoted)这里是一个null。空引用初始的时候没有运行时类型,但是可能会转换为任何类型,引用类型默认值就是null.

JVM规范并没有规定null如何正确的编码表示

1.5     Runtime Data Areas

运行时数据区域。

The Java virtual machine defines various runtime data areas that are usedduring

execution of a program. Some of these data areas are created on Javavirtual

machine start-up and are destroyed only when the Java virtual machineexits. Other

data areas are per thread. Per-thread data areas are created when a threadis created

and destroyed when the thread exits.

JVM定义了各种运行时的数据区域在执行程序时被使用。一些数据区域在JVM启动时被创建,退出时被销毁,还有一些数据区域属于线程使用,线程数据区域当线程创建时被创建,线程退出时被销毁。

1.5.1     The pc Register

PC寄存器

The Java virtual machine can support many threads of execution at once(JLS §17).

Each Java virtual machine thread has its own pc (program counter)register. At any

point, each Java virtual machine thread is executing the code of a singlemethod,

namely the current method (§2.6) for that thread. If that method is not native, the

pc register contains the address of the Java virtual machineinstruction currently

being executed. If the method currently being executed by the thread is native, the

value of the Java virtual machine’s pc register is undefined.The Java virtual

machine’s pc register is wideenough to hold a returnAddress or a native pointer

on the specific platform.

JVM能够支持多个线程立刻执行,JVM线程之间都有自己的PC寄存器。在任何一个时间点,JVM线程执行自己独立的方法代码。换句话说(namely)当前方法为该线程。如果这个方法不是本地方法,这个pc寄存器包含了当前需要被执行的JVM机器指令地址。如果这个当前被线程执行的方法是本地方法,那么JVM寄存器的值是未定义。JVM寄存器在特定平台上有足够的空间来容纳返回地址或者本地指针。

1.5.2     Java Virtual Machine Stacks

JVM 栈

Each Java virtual machine thread has a privateJava virtual machine stack, created

at the same time as the thread.3 A Java virtual machine stack stores frames (§2.6). A

Java virtual machine stack is analogous to the stack of a conventionallanguage such

as C: it holds local variables and partial results, and plays a part inmethod invocation

and return. Because the Java virtual machine stack is never manipulated

directly except to push and pop frames, frames may be heap allocated. Thememory

for a Java virtual machine stack does not need to be contiguous.

The Java virtual machine specification permits Java virtual machine stacks

either to be of a fixed size or to dynamically expand and contract asrequired by

the computation. If the Java virtual machine stacks are of a fixed size,the size of

each Java virtual machine stack may be chosen independently when thatstack is

created. A Java virtual machine implementation may provide the programmeror

the user control over the initial size of Java virtual machine stacks, aswell as, in

the case of dynamically expanding or contracting Java virtual machinestacks,

control over the maximum and minimum sizes.

The following exceptional conditions are associated with Java virtual

machine stacks:

• If the computation in a thread requires a larger Java virtual machinestack than

is permitted, the Java virtual machine throws a StackOverflowError.

• If Java virtual machine stacks can be dynamically expanded, andexpansion is

attempted but insufficient memory can be made available to effect theexpansion,

or if insufficient memory can be made available to create the initial Java

virtual machine stack for a new thread, the Java virtual machine throws an

OutOfMemoryError.

任何JVM线程都有自己私有的JVM栈,创建于线程的某个时刻,一个JVM栈存储了许多栈帧(frame)JVM栈几乎是堆叠的类似其它常规语言。比如C:它持有一个局部变量和部分结果,并且起作用在方法调用和返回,因为这个JVM栈从来没被直接操作除了push帧和pop帧,帧有可能在堆中被分配。JVM的栈存储空间不是必须是连续的。

JVM规范许可JVM栈要么指定大小要么动态扩展和收缩(contract)根据计算的要求。

如果是固定大小的,每个栈的大小在栈被创建时可以独立选择,JVM的实现可能提供程序员或者使用者控制JVM栈的初始值大小,而(as well as),在动态扩展或者伸缩的JVM栈的情况下(the case of),需要控制最大值和最小值。

如下的异常状况和JVM的栈有关联。

如果线程计算要求比JVM栈许可的还大,JVM可能抛出StackOverflowError 错误。

如果JVM栈能动态扩展,然后尝试动态扩展但是又没有足够的内存来提供其有效的扩展或者如果没有足够的内存为一个新的线程用于创建JVM栈初始值。JVM可能抛出OutOfMemoryError错误。

补充知识: Java栈是由许多栈帧(frame)组成,一个栈帧包含一个Java方法的调用状态。当现成调用一个Java方法时,JVM压入一个新的栈帧到该线程的Java栈中;当方法返回时,这个栈帧被从Java栈中弹出并抛弃 [3]。
  栈帧由三部分构成:局部变量区,操作数栈和帧数据区 [4]。局部变量区被组织为一个数组,该数组单个元素长度为一个JVM字(注意不是一个机器字),用于保存位于方法内的局部变量数据;操作数栈也是被组织为一个单位长度为一个JVM字的数组,不过该数组只能通过标准栈操作(push和pop)访问,该栈是被(逻辑上的)CPU的ALU唯一识别的操作数来源。关于局部变量和操作数栈的操作详见下段。帧数据区保存一些数据来支持常量池解析、正常方法返回以及异常派发机制。
  如有分别存在局部变量区的a,b,c,要计算c=a+b,则使用4条指令:

1.     读局部变量区[0]的值,压入操作数栈;

2.     读局部变量区[1]的值,压入操作数栈;

3.     弹出操作数栈栈顶值,再弹出操作数栈栈顶值,相加,把结果压入操作数栈;

4.     弹出操作数栈栈顶值,写入局部变量区[2]。

1.5.3     Heap

The Java virtual machine has a heap that is shared among all Java virtualmachine

threads. The heap is the runtime data area from which memory for all classinstances

and arrays is allocated.

The heap is created on virtual machine start-up. Heap storage for objectsis

reclaimed by an automatic storage management system (known as agarbagecollector);

objects are never explicitly deallocated. The Java virtual machine assumes

no particular type of automatic storage management system, and the storagemanagement

technique may be chosen according to the implementor’s systemrequirements.

The heap may be of a fixed size or may be expanded as required by the

computation and may be contracted if a larger heap becomes unnecessary.The

memory for the heap does not need to be contiguous.

A Java virtual machine implementation may provide the programmer or the

user control over the initial size of the heap, as well as, if the heapcan be dynamically

expanded or contracted, control over the maximum and minimum heap size.

The following exceptional condition is associated with the heap:

• If a computation requires more heap than can be made available by theautomatic

storage management system, the Java virtual machine throws an Out-OfMemoryError.

JVM 有一个堆区域供JVM所有的线程共享。堆内存是运行时的数据区域是给所有类实例和数组分配内存空间。

堆是在JVM启动的时候创建。堆存储对象通过动态存储管理系统回收 (众所周知的垃圾回收器),对象从来没有被显示的释放(deallocated,allocated:分配)。JVM 假设没有特定类型的自动存储管理系统,那么这个存储管理技术可能通过实现者的系统要求来选择。

堆空间或者固定大小或者可能根据计算要求被扩展或者收缩如果有更大的堆变成不是必须的。堆内存空间不一定需要连续。JVM实现提供程序员或者用户控制初始化堆内存空间的大小,而如果堆能够动态扩展和收缩,控制堆的最大和最小范围值。

如下的异常状况和JVM的堆有关联。

如果计算要求的堆空间超过动态管理器系统能使用的空间,JVM抛出Out-OfMemoryError

1.5.4     Method Area

方法区

The Java virtual machine has a method area that is shared amongall Java virtual

machine threads. The method area is analogous to the storage area forcompiled

code of a conventional language or analogous to the “text” segment in anoperating

system process. It stores per-class structures such as the runtimeconstant pool, field

and method data, and the code for methods and constructors, including thespecial

methods (§2.9) used in class and instance initialization and interfaceinitialization.

The method area is created on virtual machine start-up. Although themethod

area is logically part of the heap, simple implementations may choose notto either

garbage collect or compact it. This version of the Java virtual machinespecification

does not mandate the location of the method area or the policies used tomanage

compiled code. The method area may be of a fixed size or may be expanded

as required by the computation and may be contracted if a larger methodarea

becomes unnecessary. The memory for the method area does not need to becontiguous.

A Java virtual machine implementation may provide the programmer or the

user control over the initial size of the method area, as well as, in thecase of a varying-

size method area, control over the maximum and minimum method area size.

The following exceptional condition is associated with the method area:

• If memory in the method area cannot be made available to satisfy anallocation

request, the Java virtual machine throws an OutOfMemoryError.

JVM方法区是被所有的JVM线程所共享。方法区和传统的编译代码储存区(storage area for compiled code)或者操作系统进程的段类似,它存储了每一个类的结构信息比如运行时常量池,字段和方法数据,普通方法和构造方法字节码还包括特殊的方法被类和实例初始化以及接口初始化。方法区在JVM启动时创建,当然方法区是堆的逻辑组成,简单的虚拟机实现可以选择没有实现垃圾收集器  这个版本的JVM规范不限定实现方法区的内存位置和管理编译代码时策略,方法区可以指定固定大小或者根据计算要求扩展其大小或者如果有大的方法区变成不必须收缩其大小。方法区的内存不一定连续,JVM实现提供程序员或者使用者控制其初始化的大小,并且在可变大小的方法区情况下,控制最大和最小方法区大小。

如下异常情况是和方法区有关

如果内存不能被方法区安全有效的分配,JVM抛出OutOfMemoryError

1.5.5     Runtime Constant Pool

运行时常量池

A runtimeconstant pool is a per-class or per-interface runtime representation of the

constant_pool table in a class file (§4.4). It contains several kinds of constants,

ranging from numeric literals known at compile time to method and fieldreferences

that must be resolved at runtime. The runtime constant pool serves afunction similar

to that of a symbol table for a conventional programming language,although it

contains a wider range of data than a typical symbol table.

Each runtime constant pool is allocated from the Java virtual machine’s

method area (§2.5.4). The runtime constant pool for a class or interfaceis constructed

when the class or interface is created (§5.3) by the Java virtual machine.

The following exceptional condition is associated with the construction ofthe

runtime constant pool for a class or interface:

• When creating a class or interface, if the construction of the runtimeconstant

pool requires more memory than can be made available in the method area of

the Java virtual machine, the Java virtual machine throws an OutOfMemory-

Error.

运行时常量池是每个类或者接口在运行时在类文件中分配的常量池表,包含不同的常量,

从编译时可知的数值型范围必须在到运行期解析后才能获得的方法或者字段引用。运行时常量池服务功能类似传动编程语言的符号表。尽管如此,相对普通符号表包含更宽广的数据范围。

任何一个运行时常量池从JVM的方法区中被分配。在类或者接口被JVM创建时其常量池同时被创建。

如下的异常情况是和类或者接口的运行时常量池结构有关。

当创建类或者接口时,如果运行时常量池结构要求的内存比被JVM创建的方法区可使用内存还多,这JVM抛出OutOfMemory-Error

1.5.6     Native Method Stacks

本地方法栈

An implementation of the Java virtual machine may use conventional stacks,colloquially

called “C stacks,” to support native methods, methods written in a language

other than the Java programming language. Native method stacks may also be

used by the implementation of an interpreter for the Java virtualmachine’s instruction

set in a language such as C. Java virtual machine implementations thatcannot

load native methods and that donot themselves rely on conventional stacks need

not supply native method stacks. If supplied, native method stacks aretypically allocated

per thread when each thread is created.

The Java virtual machine specification permits native method stacks eitherto

be of a fixed size or to dynamically expand and contract as required bythe computation.

If the native method stacks are of a fixed size, the size of each native

method stack may be chosen independently when that stack is created. Inany

case, a Java virtual machine implementation may provide the programmer orthe

user control over the initial size of the native method stacks. In thecase of

varying-size native method stacks, it may also make available control overthe

maximum and minimum method stack sizes.

The following exceptional conditions are associated with native method

stacks:

• If the computation in a thread requires a larger native method stackthan is

permitted, the Java virtual machine throws a StackOverflowError.

• If native method stacks can be dynamically expanded and native methodstack

expansion is attempted but insufficient memory can be made available, orif

insufficient memory can be made available to create the initial nativemethod

stack for a new thread, the Java virtual machine throws an OutOfMemory-Error.

JVM 可能使用常规栈称之为C栈,来支持本地方法。本地方法是被java其它的语言编写。本地方法栈也可能使用被C语言实现了的JVM指令解释器。JVM不能加载本地方法和常规栈本身不依赖本地方法栈,如果支持,本地方法栈在在每个线程创建时被创建。

JVM规范许可本地方法栈要么固定大小,要么根据计算要求动态扩展和收缩。如果本地方法栈是固定大小,这个本地方法栈的固定大小是依赖于栈何时创建,在任何情况下,JVM实现提供程序员或者使用者控制本地方法栈的初始化大小。在这种情况下,不同大小的本地方法栈可能会控制栈的最大值和最小值。

一下异常情况和和本地方法栈有关:

如果线程计算请求比允许的本地方法栈大,JVM抛出StackOverflowError。

如果本地方法栈不能动态扩展和本地方法栈扩展的请求但是没有足够(insufficient)有效的内存,或者没有足够的内存在新线程创建本地方法栈初始化的时候被分配。JVM抛出

OutOfMemoryError

1.6    Frames

A frame is used to store dataand partial results, as well as to perform dynamic linking,

return values for methods, and dispatch exceptions.

A new frame is created each time a method is invoked. A frame is destroyed

when its method invocation completes, whether that completion is normal orabrupt

(it throws an uncaught exception). Frames are allocated from the Javavirtual

machine stack (§2.5.2) of the thread creating the frame. Each frame hasits own

array of local variables (§2.6.1), its own operand stack (§2.6.2), and areference to

the runtime constant pool (§2.5.5) of the class of the current method.

(A frame may be extended with additional implementation-specificinformation,

such as debugging information.)

The sizes of the local variable array and the operand stack are determinedat

compile time and are supplied along with the code for the methodassociated with

the frame (§4.7.3). Thus the size of the frame data structure depends onlyon the

implementation of the Java virtual machine, and the memory for thesestructures

can be allocated simultaneously on method invocation.

Only one frame, the frame for the executing method, is active at any pointin a

given thread of control. This frame is referred to as thecurrentframe, and its

method is known as the current method. The class in which the current method is

defined is the current class. Operations on local variables and theoperand stack

are typically with reference to the current frame.

A frame ceases to be current if its method invokes another method or ifits

method completes. When a method is invoked, a new frame is created and

becomes current when control transfers to the new method. On methodreturn, the

current frame passes back the result of its method invocation, if any, tothe previous

frame. The current frame is then discarded as the previous frame becomesthe

current one.

Note that a frame created by a thread is local to that thread and cannotbe referenced

by any other thread.

栈帧用来存储数据和特定的结果,以及执行动态链接,返回方法的结果和追踪异常。

一个新的栈帧在方法被调用的时刻创建,当一个方法调用结束的时候销毁,无论(whether that)一个方法正常结束或者意外(可能没有捕获到异常),栈帧在JVM线程栈创建帧的时候分配。每个栈帧都有自己的局部变量数组,栈操作数,和运行时类当前方法常量池(一个帧可能被扩展添加其他一些特殊信息,比如调试信息)。

局部变量数组的大小和栈操作数据是在编译时刻和单独提供的方法代码关联的帧决定的。帧数据结构的大小依赖这JVM的实现,内存结构在方法被调用的时候同时分配。

只有一个帧,该帧对应执行的方法,是活跃在任意一点给定的控制线程。这个帧被当做当前帧,对应的方法称为当前方法,当前方法所在的类称之为当前类,操作本地变量和操作数栈通常与当前栈帧关联。

当前的帧结束当一个方法调用另外一个方法或者如果方法结束。当方法被调用,一个新的帧被创建并且被当做当前帧当控制权传递给这个新方法时。当方法返回,这个当前帧通过返回调用方法的结果,如果有给前一个帧,这个当前帧然后丢弃,前一个帧又成为当前帧。

注意,帧的是被线程创建的,属于线程的局部,二不能被其它线程引用。

1.6.1     Local Variables

Each frame (§2.6) contains an array of variables known as itslocalvariables. The

length of the local variable array of a frame is determined at compiletime and supplied

in the binary representation of a class or interface along with the codefor the

method associated with the frame (§4.7.3).

A single local variable can hold a value of type boolean, byte, char, short,

int, float, reference, or returnAddress. A pair of local variables can hold a

value of type long or double.

Local variables are addressed by indexing. The index of the first localvariable

is zero. An integer is considered to be an index into the local variablearray if and

only if that integer is between zero and one less than the size of thelocal variable

array.

A value of type long or type double occupies two consecutive local variables.

Such a value may only be addressed using the lesser index. For example, a

value of type double stored in the local variable array at indexnactually occupies

the local variables with indicesnandn +1; however, the local variable at index

n +1 cannot be loaded from. It can be stored into. However,doing so invalidates

the contents of local variable n.

The Java virtual machine does not requirento be even. In intuitive terms, values

of types double and long need not be 64-bitaligned in the local variables

array. Implementors are free to decide the appropriate way to representsuch values

using the two local variables reserved for the value.

The Java virtual machine uses local variables to pass parameters on method

invocation. On class method invocation any parameters are passed inconsecutive

local variables starting from local variable0. On instance method invocation,

local variable 0 is always used to pass a reference to the object on whichthe

instance method is being invoked (this in the Javaprogramming language). Any

parameters are subsequently passed in consecutive local variables startingfrom

local variable 1.

 

每个栈帧都包含变量数组,称之为局部变量区,局部变量栈帧数组的长度是由编译时确定, 并且存储于类或者接口的二进制表示之中,通过方法的code属性提供给栈帧使用。

一个单独的局部变量包含类型有布尔、字节、字符、短整型、整型、浮点型、引用类型和返回地址类型,两个局部变量能包含长整型和双精度类型。

局部变量通过索引来查找,第一个局部变量的索引是0。一个整数在局部变量数组中被当做一个索引,并且是这个整数取值在0和局部变量数组长度之间。

长整型和双精度浮点数需要占用两个连续的局部变量,比如一个值可能仅仅使用低位索引来寻址,比如,一个双精度的值存储在局部变量数组索引为n的位置实际上这个双精度变量应该是占了n到n+1两个局部变量,尽管如此,局部变量在n+1这个位置不会被读取,但是会被直接写入的,尽管如此,这样做使局部变量n的内容失效。

JVM不要求n一定是偶数,在局部变量数组中double和long不一定要求必须是64位,也不要求存储在两个连续的局部变量当中。可以自由决定选择适当的方式使用两个局部变量来存储一个double或者long值

JVM通过局部变量来传递参数给方法的调用,一个类方法调用的任何参数传递在连续的从0开始的局部变量。一个实例方法调用,第0个局部变量总是被传递过来的此实例方法被调用的对象引用使用(this),任何参数传递在连续的局部变量都是从1开始。

1.6.2     Operand Stacks

操作数栈

Each frame (§2.6) contains a last-in-first-out (LIFO) stack known as itsoperand

stack. The maximum depth of the operand stack of a frame isdetermined at compile

time and is supplied along with the code for the method associated withthe frame

(§4.7.3).

Where it is clear by context, we will sometimes refer to the operand stackof

the current frame as simply the operand stack.

The operand stack is empty when the frame that contains it is created. The

Java virtual machine supplies instructions to load constants or valuesfrom local

variables or fields onto the operand stack. Other Java virtual machineinstructions

take operands from the operand stack, operate on them, and push the resultback

onto the operand stack. The operand stack is also used to prepare parametersto be

passed to methods and to receive method results.

For example, the iadd instruction adds two int values together. Itrequires

that the int values to be added bethe top two values of the operand stack, pushed

there by previous instructions. Both of the int values are popped fromthe operand

stack. They are added, and their sum is pushed back onto the operandstack.

Subcomputations may be nested on the operand stack, resulting in valuesthat can

be used by the encompassing computation.

Each entry on the operand stack can hold a value of any Java virtualmachine

type, including a value of type long or type double.

Values from the operand stack must be operated upon in ways appropriate to

their types. It is not possible, for example, to push two int values andsubsequently

treat them as a long or to push two float values and subsequently add

them with an iadd instruction. A small number of Java virtual machineinstructions

(the dup instructions andswap) operate on runtimedata areas as raw values

without regard to their specific types; these instructions are defined insuch a way

that they cannot be used to modify or break up individual values. Theserestrictions

on operand stack manipulation are enforced through class file verification

(§4.10).

At any point in time an operand stack has an associated depth, where avalue

of type long or double contributes two unitsto the depth and a value of any other

type contributes one unit.

每个栈帧都包含一个先进先出的队栈交操作数栈,一个帧的操作数栈的最大值在编译的时候就已经确定,通过方法的Code属性提供给帧使用。

我们通常把当前帧指向的操作的栈叫操作数栈。

当操作数所包含的帧刚被创建的时候,这个操作数栈还是空的。JVM提供指令来加载常量或者局部变量或者属性值压入操作数栈。其它JVM指令从操作数栈取走操作数,操作数栈也被使用在方法参数传递以及方法结果的接受。

比如:iadd指令 需要把两个int值相加,它要求int值通过前一个指令被添加到操作数栈的顶部,两个in值都被操作数栈弹出,然后相加,其结果值又被压入到操作数栈。子运算可以被嵌套(nested)进行, 结果值可能被外围计算所使用。

每个操作数栈能处理任何JVM数据类型包括long和double。

操作数栈必须向上转换成合适的类型,这是不可能的,比如把两个int类型的值入栈然后当做long类型,或者把两个float值入栈然后使用iadd指令,在少数JVM指令(比如dup和swap指令)操作和运行时数据区域当做原始值而不考虑(regard to)他们特定的类型,他们的指令被定义成特定的方式,并且不能修改或者破坏其数据值,这些限制在操作数栈操作被强制(enforced)通过类文件校验。

在任意时刻操作数栈都有一个相关的栈深度,long或者double类型的值,贡献两个单元的深度,其它类型贡献一个单元的深度

1.6.3     Dynamic Linking

动态链接

Each frame (§2.6) contains a reference to the runtime constant pool(§2.5.5) for

the type of the current method to supportdynamic linkingof the method code.The

class file code for a method refers to methods to be invokedand variables to be

accessed via symbolic references. Dynamic linking translates thesesymbolic

method references into concrete method references, loading classes asnecessary

to resolve as-yet-undefined symbols, and translates variable accesses intoappropriate

offsets in storage structures associated with the runtime location ofthese

variables.

This late binding of the methods and variables makes changes in otherclasses

that a method uses less likely to break this code.

每个帧包含一个引用 运行时常量池的引用来支持当前方法代码实现动态链接。在类文件代码中,方法引用或者方法调用另外一个方法和变量都是通过符号引用来方法的。

类文件代码里面的方法被调用和被引用访问的变量。动态链接把通用符号引用转换为具体的方法引用。类加载将解决掉不必须的无效的符号。然后把变量访问转换为变量存储结构在运行时正确的偏移位置。

晚期绑定(late bingding)方法和变量,使用其它类的方法在改变时,不会对调用的方法有影响。

1.6.4     Normal Method Invocation Completion

正常方法调用完成

A method invocation completes normallyif that invocation does not cause anexception

(§2.10) to be thrown, either directly from the Java virtual machine or asa result

of executing an explicit throw statement. If the invocation of the current method

completes normally, then a value may be returned to the invoking method.This

occurs when the invoked method executes one of the return instructions(§2.11.8),

the choice of which must be appropriate for the type of the value beingreturned (if

any).

The current frame (§2.6) is used in this case to restore the state of theinvoker,

including its local variables and operand stack, with the program counterof the

invoker appropriately incremented to skip past the method invocationinstruction.

Execution then continues normally in the invoking method’s frame with the

returned value (if any) pushed onto the operand stack of that frame.

如果一个方法调用没有导致任何异常抛出包括直接从JVM虚拟机中返回或者执行时候直接从异常语句中抛出,那么这个方法就是正常调用完成。如果当前方法正常结束,那么会有一个调用方法的返回值。这发生在当调用方法执行其中一个返回指令,具体选择哪个返回指令取决于返回值的类型。

1.6.5     Abrupt Method Invocation Completion

异常方法调用完成

A method invocation completes abruptlyif execution of a Java virtual machine

instruction within the method causes the Java virtual machine to throw anexception

(§2.10), and that exception is not handled within the method. Execution ofanathrow

instruction also causes an exception to be explicitly thrown and, if theexception

is not caught by the current method, results in abrupt method invocationcompletion.

A method invocationthat completes abruptly never returns a value to its invoker.

如果在方法内执行JVM指令导致JVM抛出了异常和在方法体内异常未处理,那么这个方法调用异常完成。或者一个athrow指令也可能导致异常显示抛出,如果异常没有被当前方法捕获,异常方法调用的结果完成。一个方法调用异常完成从来不会把返回值给它的调用者。

1.7     Representation of Objects

1.8     Floating-Point Arithmetic

1.8.1     Java Virtual Machine Floating-PointArithmetic and IEEE 754

JVM浮点数计算和IEEE754

The key differences between the floating-point arithmetic supported by theJava virtual

machine and the IEEE 754 standard are:

• The floating-point operations of the Java virtual machine do not throwexceptions,

trap, or otherwise signal the IEEE 754 exceptional conditions of invalid

operation, division by zero, overflow, underflow, or inexact. The Javavirtual

machine has no signaling NaN value.

• The Java virtual machine does not support IEEE 754 signalingfloating-point

comparisons.

• The rounding operations of the Java virtual machine always use IEEE 754

round to nearest mode. Inexact results are rounded to the nearestrepresentable

value, with ties going to the value with a zero least-significant bit.This is the

IEEE 754 default mode. But Java virtual machine instructions that convertvalues

of floating-point types to values of integral types round toward zero. The

Java virtual machine does not give any means to change the floating-point

rounding mode.

• The Java virtual machine does not support either the IEEE 754 singleextended

or double extended format, except insofar as the double anddoubleextended-

exponent value sets may be said to support the single extended format.

The float-extended-exponent and double-extended-exponent value sets,

which may optionally be supported, do not correspond to the values of the

IEEE 754 extended formats: the IEEE 754 extended formats require extended

precision as well asextended exponent range.

被JVM支持的浮点数计算和IEEE754有几个关键的不同:

JVM浮点数操作不会抛出异常,或者IEEE754其它的异常条件,当在遇到被0除,上线溢出,下线溢出。

JVM不支持IEEE754信号浮点比较。

JVM总是使用IEEE754就近的舍入模式。

JVM不支持IEEE754的单精度和双精度扩展模式。

1.8.2     Floating-Point Modes

浮点数模式

Every method has a floating-point mode, which is eitherFP-strictornotFP-strict.

The floating-point mode of a method is determined by the setting of the

ACC_STRICT flag of the access_flags item of the method_info structure (§4.6)

defining the method. A method for which this flag is set is FP-strict;otherwise,

the method is not FP-strict.

Note that this mapping of the ACC_STRICT flag implies that methods in

classes compiled by a compiler in JDK release 1.1 or earlier areeffectively not

FP-strict.

每个方法都有一个浮点数模式,要么是FP或者非FP,方法的浮点数模式是由该method_info结构访问标志ACC_STRICT决定,如果为真,就是FP,否则是非FP。

需要注意,被JDK1.1或者更早编译的类文件方法标志无效。

We will refer to an operand stack as having a given floating-point modewhen

the method whose invocation created the frame containing the operand stackhas

that floating-point mode. Similarly, we will refer to a Java virtualmachine instruction

as having a given floating-point mode when the method containing that

instruction has that floating-point mode.

If a float-extended-exponent value set is supported (§2.3.2), values oftype

float on an operand stack that is not FP-strict may range overthat value set

except where prohibited by value set conversion (§2.8.3). If adoubleextended-

exponent value set is supported (§2.3.2), values of type double on an

operand stack that is not FP-strict may range over that value set exceptwhere prohibited

by value set conversion.

In all other contexts, whether on the operand stack or elsewhere, andregardless

of floating-point mode, floating-point values of type float and double may

only range over the float value set and double value set, respectively. Inparticular,

class and instance fields, array elements, local variables, and methodparameters

may only containvalues drawn from the standard value sets.

 

1.8.3     Value Set Conversion

数据集转换

An implementation of the Java virtual machine that supports an extendedfloating-

point value set is permitted or required, under specified circumstances,to map a

value of the associated floating-point type between the extended and thestandard

value sets. Such a value set conversionis not a type conversion, but a mapping

between the value sets associated with the same type.

Where value set conversion is indicated, an implementation is permitted to

perform one of the following operations on a value:

• If the value is of type float and is not an element of the float value set, it maps

the value to the nearest element of the float value set.

• If the value is of type double and is not an element of the double value set, it

maps the value to the nearest element of the double value set.

In addition, where value set conversion is indicated certain operationsare

required:

• Suppose execution of a Java virtual machine instruction that is notFP-strict

causes a value of type float to be pushed onto an operand stack that is

FP-strict, passed as a parameter, or stored into a local variable, afield, or an

element of an array. If the value is not an element of the float valueset, it maps

the value to the nearest element of the float value set.

• Suppose execution of a Java virtual machine instruction that is not FP-strict

causes a value of type double to be pushed onto an operand stack that is

FP-strict, passed as a parameter, or stored into a local variable, afield, or an

element of an array. If the value is not an element of the double valueset, it

maps the value to the nearest element of the double value set.

Such required value set conversions may occur as a result of passing aparameter

of a floating-point type during method invocation, including native method

invocation; returning a value of a floating-point type from a method thatis not

FP-strict to a method that is FP-strict; or storing a value of afloating-point type

into a local variable, a field, or an array in a method that is notFP-strict.

Not all values from an extended-exponent value set can be mapped exactlyto

a value in the corresponding standard value set. If a value being mappedis too

large to be represented exactly (its exponent is greater than thatpermitted by the

standard value set), it is converted to a (positive or negative) infinityof the corresponding

type. If a value being mapped is too small to be represented exactly (its

exponent is smaller than that permitted by the standard value set), it isrounded to

the nearest of a representable denormalized value or zero of the samesign.

Value set conversion preserves infinities and NaNs and cannot change the

sign of the value being converted. Value set conversion has no effect on avalue

that is not of afloating-point type.

1.9     Special Methods

At the level of the Java virtual machine, every constructor written in theJava programming

language (JLS §8.8) appears as aninstance initialization methodthat

has the special name <init>. This name is supplied by a compiler. Because the

name <init> is not a valididentifier, it cannot be used directly in a program written

in the Java programming language. Instance initialization methods may be

invoked only within the Java virtual machine by theinvokespecialinstruction, and

they may be invoked only on uninitialized class instances. An instanceinitialization

method takes on the access permissions (JLS §6.6) of the constructor from

which it was derived.

在JVM层面上,每个java语言中的构造方法是以一个实例初始化方法出现的,它叫<init>。 这个方法在编译时被支持,因为这个名字不是关键字,它在java语言中不能直接被使用。实例初始化方法只能通过JVM的invokespecial指令来调用。仅仅在类实例被初始化的时候调用。

A class or interface has at most oneclass or interface initializationmethod

and is initialized (§5.5) by invoking that method. The initializationmethod of a

class or interface has the special name <clinit>,takes no arguments,and is

void (§4.3.3) 5. In a class file whose versionnumber is 51.0 or above, the method

must additionally have its ACC_STATIC flag (§4.6) set in order to be the class or

interface initialization method.6 The name <clinit> is supplied by a compiler.

Because the name <clinit> is not a valid identifier, it cannot be used directly ina

program written in the Java programming language. Class and interfaceinitialization

methods are invoked implicitly by the Java virtual machine; they are never

invoked directly from any Java virtual machine instruction, but areinvoked only

indirectly as part of the class initialization process.

A method is signature polymorphicif and only if all of the followingconditions

hold 7:

• It is declared in the java.lang.invoke.MethodHandle class.

• It has a single formal parameter of type Object[].

• It has a return type of Object.

• It has the ACC_VARARGS and ACC_NATIVE flags set.

The Java virtual machine gives special treatment to signature polymorphic

methods in the invokevirtualinstruction, in order to effect invocationof amethod

handle. A method handle is a typed, directly executablereference to an underlying

method, constructor, field, or similar low-level operation (§5.4.3.5),with optional

transformations of arguments or return values. These transformations arequite general,

and include such patterns as conversion, insertion, deletion, andsubstitution.

See the java.lang.invokepackage in the Java SEplatform API for more information.

类或者接口至少有超过一个初始化方法,当方法被调用的时候初始化。类或者接口初始化方法被命名为<clinit>.没有参数,并且是void返回类型。为了类或者接口初始化方法。类文件在版本51及以上方法必须增加ACC_STATIC标志集。<clinit>方法又编译器支持,因为<clinit>不是java标识符,不能直接被java程序语言使用。类或者结构初始化方法隐式的被JVM调用。它们从来不会被JVM指令直接调用。但是它们被类初始化进程调用

1.10       Exceptions

An exception in the Java virtual machine is represented by an instance ofthe class

Throwable or one of its subclasses. Throwing an exception resultsin an immediate

nonlocal transfer of control from the point where the exception wasthrown.

Most exceptions occur synchronously as a result of an action by the threadin

which they occur. An asynchronous exception, by contrast, can potentiallyoccur at

any point in the execution of a program. The Java virtual machine throwsan exception

for one of three reasons:

1. An abnormal execution condition was synchronously detected by the Javavirtual

machine. These exceptions are not thrown at an arbitrary point in theprogram,

but only synchronously after execution of an instruction that either:

◆ Specifies the exception as a possible result, such as:

❖ When the instructionembodies an operation that violates the

semantics of the Java programming language, for example

indexing outside the bounds of an array.

❖ When an error occursin loading or linking part of the program.

◆ Causes some limit on a resource to be exceeded, forexample when too much

memory is used.

一个异常在JVM中是 Throwable或者子类的一个实例。抛出一个异常的结果是控制权的转移从异常抛出的地方。大部分异常同步发生是由于线程执行了某种操作。异步异常是发生在程序可能发生任何异常的地方,JVM抛出异常有如下三个原因。

JVM同步检测到非正常执行条件。这些异常没有在程序任意点抛出,而是在执行了指令以后同步抛出。比如

       当执行包含一些操作违反java程序语言语义,比如索引超出了数组的界限。

加载或者链接程序部分时发生错误。

       一些限制资源被执行比如太多的内存被使用。

2. An athrow instruction wasexecuted.

异常指令被执行

3. An asynchronous exception occurred because:

• The stop method of class Thread or ThreadGroup was invoked, or

• An internal error occurred in the Java virtual machine implementation.

The stop methods may be invokedby one thread to affect another thread or all

the threads in a specified thread group. They are asynchronous becausethey

may occur at any point in the execution of the other thread or threads. Aninternal

error is considered asynchronous (§6.3).

异步异常发生的原因

Thread或者ThreadGroup的stop方法被执行。Stop方法可能被执行仅仅是在线程影响另外一个线程或者所有的组,他们异步,因为他们可能发生在执行线程的任何时刻。

A Java virtual machine may permit a small but bounded amount of executionto

occur before an asynchronous exception is thrown. This delay is permittedto allow

optimized code to detect and throw these exceptions at points where it ispractical to

handle them while obeying the semantics of the Java programming language.8

Exceptions thrown by the Java virtual machine are precise: when the transfer

of control takes place, all effects of the instructions executed beforethe point from

which the exception is thrown must appear to have taken place. Noinstructions

that occur after the point from which the exception is thrown may appearto have

been evaluated. If optimized code has speculatively executed some of theinstruc-

tions which follow the point at which the exception occurs, such code mustbe

prepared to hide this speculative execution from the user-visible state ofthe program.

Each method in the Java virtual machine may be associated with zero ormore

exception handlers. An exception handler specifies the range of offsetsinto the

Java virtual machine code implementing the method for which the exceptionhandler

is active, describes the type of exception that the exception handler isable to

handle, and specifies the location of the code that is to handle thatexception. An

exception matches an exception handler if the offset of the instructionthat caused

the exception is in the range of offsets of the exception handler and theexception

type is the same class as or a subclass of the class of exception that theexception

handler handles. When an exception is thrown, the Java virtual machinesearches

for a matching exception handler in the current method. If a matchingexception

handler is found, the system branches to the exception handling codespecified by

the matched handler.

If no such exception handler is found in the current method, the current

method invocation completes abruptly (§2.6.5). On abrupt completion, theoperand

stack and local variables of the current method invocation are discarded,and

its frame is popped, reinstating the frame of the invoking method. Theexception

is then rethrown in the context of the invoker’s frame and so on,continuing up the

method invocation chain. If no suitable exception handler is found beforethe top

of the method invocation chain is reached, the execution of the thread inwhich the

exception was thrown is terminated.

The order in which the exception handlers of a method are searched for amatch

is important. Within a class file the exception handlers for each method are stored

in a table (§4.7.3). At runtime, when an exception is thrown, the Javavirtual machine

searches the exception handlers of the current method in the order thatthey appear in

the corresponding exception handler table in the class file, starting fromthe beginning

of that table.

Note that the Java virtual machine does not enforce nesting of or anyordering of

the exception table entries of a method. The exception handling semanticsof the Java

programming language are implemented only through cooperation with thecompiler

(§3.12). When class files are generated by some other means, the definedsearch

procedure ensures thatall Java virtual machines will behave consistently.

1.11       InstructionSet Summary

指令集总结

A Java virtual machine instruction consists of a one-byteopcodespecifying the

operation to be performed, followed by zero or moreoperandssupplying arguments

or data that are used by the operation. Many instructions have no operandsand consist

only of an opcode.

Ignoring exceptions, the inner loop of a Java virtual machine interpreteris

effectively

do {

atomically calculate pc and fetchopcode at pc;

if (operands) fetch operands;

execute the action for the opcode;

} while (there is more to do);

The number and size of the operands are determined by the opcode. If an

operand is more than one byte in size, then it is stored inbig-endianorder—

high-order byte first. For example, an unsigned 16-bit index into thelocal variables

is stored as two unsigned bytes,byte1andbyte2, such that its valueis

(byte1 << 8) | byte2

The bytecode instruction stream is only single-byte aligned. The twoexceptions are

the tableswitch and lookupswitchinstructions, whichare padded to force internal

alignment of some of their operands on 4-byte boundaries.

The decision to limit the Java virtual machine opcode to a byte and toforgo

data alignment within compiled code reflects a conscious bias in favor ofcompactness,

possibly at the cost of some performance in naive implementations. A

one-byte opcode also limits the size of the instruction set. Not assumingdata

alignment means that immediate data larger than a byte must be constructed

from bytes at runtimeon many machines.

JVM指令结构是由一个代表某种操作的操作码(opcode)和0或者多个此操作参数和数据的操作数(operands)组成。许多指令没有操作数,只有操作码

1.11.1             Typesand the Java Virtual Machine

数据类型和虚拟机

Most of the instructions in the Java virtual machine instruction setencode type

information about the operations they perform. For instance, theiloadinstruction

loads the contents of a local variable, which must be an int, onto the operandstack.

The fload instruction does thesame with a float value. The twoinstructions may

have identical implementations, but have distinct opcodes.

For the majority of typed instructions, the instruction type isrepresented

explicitly in the opcode mnemonic by a letter:ifor an int operation,l for long, s

for short, b for byte, c for char, f for float, d for double, and a for reference.

Some instructions for which the type is unambiguous do not have a typeletter

in their mnemonic. For instance,arraylengthalways operates on anobject that

is an array. Some instructions, such asgoto, an unconditional control transfer, do

not operate on typed operands.

Given the Java virtual machine’s one-byte opcode size, encoding types into

opcodes places pressure on the design of its instruction set. If eachtyped instruction

supported all of the Java virtual machine’s runtime data types, therewould be

more instructions than could be represented in a byte. Instead, theinstruction set

of the Java virtual machine provides a reduced level of type support forcertain

operations. In other words, the instruction set is intentionally notorthogonal. Separate

instructions can be used to convert between unsupported and supported data

types as necessary.

许多JVM指令结构集合包含了操作类型信息,比如,iload指令加载本地变量的内容,它必须加载int类型的到操作栈。Fload指令通用加载flaot值。这两个指令有许多相同之处,但是有唯一的操作码。

对于大部分的类型指令,指令类型通过操作码助记符被明确确定。I 是int操作数,l是long操作数,s是short操作数,a是引用类型操作数。一些指令类型没有助记符,比如arraylength指令总是操作数组对象,一些指令比如goto,无条件控制跳转,在类型操作中没有操作。

JVM操作码只有一个字节的长度。操作码的编码类型给指令集合设计带来压力。如果每个类型指令都支持所有JVM运行时数据类型,那么可能超过一个字节的表示,替代方案是,jvm指令集为某种特别操作提供减少类型支持。换句话说,独立指令在必要的时候被用来转换从非支持到支持数据类型。

Table 2.2 summarizes the type support in the instruction set of the Javavirtual

machine. A specific instruction, with type information, is built byreplacing theT

in the instruction template in the opcode column by the letter in the typecolumn.

If the type column for some instruction template and type is blank, thenno

instruction exists supporting that type of operation. For instance, thereis a load

instruction for type int, iload, but there is no load instruction for type byte.

Note that most instructions in Table 2.2 do not have forms for theintegral

types byte, char, and short. None have forms forthe boolean type. Compilers

encode loads of literal values of types byte and short using Java virtual

machine instructions that sign-extend those values to values of type int at compile

time or runtime. Loads of literal values of types boolean and char are

encoded using instructions that zero-extend the literal to a value of typeint at

compile time or runtime. Likewise, loads from arrays of values of type boolean,

byte, short, and char are encoded using Java virtual machine instructions that

sign-extend or zero-extend the values to values of type int. Thus, mostoperations

on values of actual types boolean, byte, char, and short are correctly

performed by instructions operating on values of computational type int.

比如,load指令类型int为iload ,但是没有为typ类型的load指令,也没有byte,char 和short.还没有boolean类型,编译器编码load类型为type,short时使用在编译或者运行时单扩展的int类型指令。

Table 2.2 Type support in the Java virtual machineinstruction set

opcode byte short int long floatdouble char reference

Tipush bipush sipush

Tconst iconst lconst fconst dconst aconst

Tload iload lload fload dload aload

Tstore istore lstore fstore dstore astore

Tinc iinc

Taload baload saload iaload laload faload daload caloadaaload

Tastore bastore

sastore

iastore lastore fastore dastore castore

aastore

Tadd iadd ladd fadd dadd

Tsub isub lsub fsub dsub

Tmul imul lmul fmul dmul

Tdiv idiv ldiv fdiv ddiv

Trem irem lrem frem drem

Tneg ineg lneg fneg dneg

Tshl ishl lshl

Tshr ishr lshr

Tushr iushr lushr

Tand iand land

Tor ior lor

Txor ixor lxor

i2T i2b i2s i2l i2f i2d

l2T l2i l2f l2d

f2T f2i f2l f2d

d2T d2i d2l d2f

Tcmp lcmp

Tcmpl fcmpl dcmpl

Tcmpg fcmpg dcmpg

if_TcmpOP if_icmpOP if_acmpOP

Treturn ireturn lreturn freturn dreturn areturn

The mapping between Java virtual machine actual types and Java virtual

machine computational types is summarized by Table 2.3.

Table 2.3 Java virtual machine actual and computationaltypes

Actual Type Computational Type Category

boolean int category 1

byte int category 1

char int category 1

short int category 1

int int category 1

float float category 1

reference reference category 1

returnAddress returnAddress category 1

long long category 2

double double category 2

Certain Java virtual machine instructions such aspopandswap operate on the

operand stack without regard to type; however, such instructions areconstrained

to use only on values of certain categories of computational types, alsogiven in

Table 2.3.

对于某些特殊的JVM指令比如pop和swap操作到操作栈,没有相关的类型,尽管如此,这些指令也会在某种类型计算分类时受到限制。

1.11.2             Loadand Store Instructions

加载和存储指令

The load and store instructions transfer values between the localvariables (§2.6.1)

and the operand stack (§2.6.2) of a Java virtual machine frame (§2.6):

• Load a local variable onto the operand stack:iload,iload_<n>,lload,

lload_<n>, fload,fload_<n>,dload,dload_<n>, aload, aload_<n>.

• Store a value from the operand stack into a local variable:istore,istore_<n>,

lstore, lstore_<n>,fstore,fstore_<n>,dstore, dstore_<n>, astore,

astore_<n>.

• Load a constant onto the operand stack:bipush,sipush,ldc, ldc_w, ldc2_w,

aconst_null, iconst_m1,iconst_<i>,lconst_<l>,fconst_<f>, dconst_<d>.

Table 2.3 Java virtual machine actual and computationaltypes

JVM支持的数据类型

Actual Type Computational Type Category

boolean int category 1

byte int category 1

char int category 1

short int category 1

int int category 1

float float category 1

reference reference category 1

returnAddress returnAddress category 1

long long category 2

double double category 2

THE STRUCTURE O 30 F THE JAVA VIRTUAL MACHINE

• Gain access to more local variables using a wider index, or to a largerimmediate

operand: wide.

Instructions that access fields of objects and elements of arrays(§2.11.5) also transfer

data to and from the operand stack.

Instruction mnemonics shown above with trailing letters between angle

brackets (for instance, iload_<n>) denote families of instructions (withmembers

iload_0, iload_1,iload_2, andiload_3in the case of iload_<n>). Such families of

instructions are specializations of an additional generic instruction (iload) that

takes one operand. For the specialized instructions, the operand isimplicit and

does not need to be stored or fetched. The semantics are otherwise thesame

(iload_0 means the same thingasiloadwith the operand0). The letter between

the angle brackets specifies the type of the implicit operand for thatfamily of

instructions: for <n>, a nonnegative integer; for<i>, an int; for<l>, a long; for

<f>, a float; and for <d>, a double. Forms for type int are used in many cases

to perform operations on values of type byte, char, and short (§2.11.1).

This notation for instruction families is used throughoutThe JavaVirtual

Machine Specification.

1.11.3             ArithmeticInstructions

运算指令

The arithmetic instructions compute a result that is typically a functionof two values

on the operand stack, pushing the result back on the operand stack. Thereare

two main kinds of arithmetic instructions: those operating on integervalues and

those operating on floating-point values. Within each of these kinds, thearithmetic

instructions are specialized to Java virtual machine numeric types. Thereis no direct

support for integer arithmetic on values of the byte, short, and char types

(§2.11.1), or for values of the boolean type; those operations are handled by

instructions operating on type int. Integer and floating-point instructionsalso differ

in their behavior on overflow and divide-by-zero. The arithmeticinstructions are as

follows:

• Add: iadd, ladd,fadd,dadd.

• Subtract: isub, lsub,fsub,dsub.

• Multiply: imul, lmul,fmul,dmul.

• Divide: idiv, ldiv,fdiv,ddiv.

• Remainder: irem, lrem, frem, drem.

INSTRUCTION SET SUMMARY 31

• Negate: ineg, lneg,fneg,dneg.

• Shift: ishl, ishr,iushr,lshl,lshr, lushr.

• Bitwise OR: ior, lor.

• Bitwise AND: iand, land.

• Bitwise exclusive OR: ixor,lxor.

• Local variable increment: iinc.

• Comparison: dcmpg, dcmpl, fcmpg, fcmpl, lcmp.

The semantics of the Java programming language operators on integer and

floating-point values (JLS §4.2.2, JLS §4.2.4) are directly supported bythe

semantics of the Java virtual machine instruction set.

The Java virtual machine does not indicate overflow during operations on

integer data types. The only integer operations that can throw anexception are the

integer divide instructions (idivandldiv) and the integer remainder instructions

(irem and lrem), which throw an ArithmeticExceptionif the divisor iszero.

Java virtual machine operations on floating-point numbers behave asspecified

in IEEE 754. In particular, the Java virtual machine requires full supportof

IEEE 754 denormalized floating-point numbers andgradualunderflow,which

make it easier to prove desirable properties of particular numericalalgorithms.

The Java virtual machine requires that floating-point arithmetic behave asif

every floating-point operator rounded its floating-point result to theresult precision.

Inexact results must be rounded to the representable valuenearest to the infinitely

precise result; if the two nearest representable values are equally near,the

one having a least significant bit of zero is chosen. This is the IEEE 754standard’s

default rounding mode, known as round to nearest mode.

The Java virtual machine uses the IEEE 754round towards zeromode when

converting a floating-point value to an integer. This results in thenumber being

truncated; any bits of the significand that represent the fractional partof the operand

value are discarded. Round towards zero mode chooses as its result thetype’s

value closest to, but no greater in magnitude than, the infinitely preciseresult.

The Java virtual machine’s floating-point operators do not throw runtime

exceptions (not to be confused with IEEE 754 floating-point exceptions).An

operation that overflows produces a signed infinity, an operation thatunderflows

produces a denormalized value or a signed zero, and an operation that hasno

mathematically definite result produces NaN. All numeric operations withNaN as

an operand produce NaN as a result.

THE STRUCTURE O 32 F THE JAVA VIRTUAL MACHINE

Comparisons on values of type long (lcmp) perform a signed comparison.

Comparisons on values of floating-point types (dcmpg,dcmpl,fcmpg,fcmpl) are

performed using IEEE754 nonsignaling comparisons.

1.11.4             TypeConversion Instructions

类型转换指令

The type conversion instructions allow conversion between Java virtualmachine

numeric types. These may be used to implement explicit conversions in usercode or

to mitigate the lack of orthogonality in the instruction set of the Javavirtual machine.

The Java virtual machine directly supports the following widening numeric

conversions:

• int to long, float, or double

• long to float or double

• float to double

The widening numeric conversion instructions arei2l,i2f,i2d, l2f, l2d, and f2d.

The mnemonics for these opcodes are straightforward given the namingconventions

for typed instructions and the punning use of 2 to mean “to.” Forinstance, the

i2d instruction converts an int value to a double. Widening numericconversions

do not lose information about the overall magnitude of a numeric value.Indeed,

conversions widening from int to long and int to double do not lose any information

at all; the numeric value is preserved exactly. Conversions widening from

float to double that are FP-strict (§2.8.2) also preserve the numericvalue

exactly; however, such conversions that are not FP-strict may loseinformation

about the overall magnitude of the converted value.

Conversion of an int or a long value to float, or of a long value to double,

may lose precision, that is, may lose some of the least significant bits ofthe value;

the resulting floating-point value is a correctly rounded version of theinteger

value, using IEEE 754 round to nearest mode.

A widening numeric conversion of an int to a long simply sign-extendsthe

two’s-complement representation of the int value to fill thewider format. A widening

numeric conversion of a char to an integral type zero-extends the representation

of the char value to fill thewider format.

Despite the fact that loss of precision may occur, widening numericconversions

never cause the Java virtual machine to throw a runtime exception (not tobe

confused with an IEEE 754 floating-point exception).

INSTRUCTION SET SUMMARY 33

Note that widening numeric conversions do not exist from integral types byte,

char, and short to type int. As noted in §2.11.1, values of type byte, char, and

short are internally widened to type int, making theseconversions implicit.

The Java virtual machine also directly supports the following narrowing

numeric conversions:

• int to byte, short, or char

• long to int

• float to int or long

• double to int, long, or float

The narrowing numeric conversion instructions arei2b,i2c,i2s, l2i, f2i, f2l,

d2i, d2l, and d2f. A narrowing numeric conversion can result in a value ofdifferent

sign, a different order of magnitude, or both; it may thereby loseprecision.

A narrowing numeric conversion of an int or long to an integral type T

simply discards all but the N lowest-order bits, where N is the number of bits used

to represent type T. This may cause the resulting value not to have the samesign

as the input value.

In a narrowing numeric conversion of a floating-point value to an integral

type T, where T is either int or long, the floating-pointvalue is converted as follows:

• If the floating-point value is NaN, the result of the conversion is an int or

long 0.

• Otherwise, if the floating-point value is not an infinity, thefloating-point value

is rounded to an integer value V using IEEE 754 round towards zero mode.

There are two cases:

◆ If T is long and this integer value can be represented as a long, then the

result is the long value V.

◆ If T is of type int and this integer value can be represented as an int, then

the result is the int value V.

• Otherwise:

THE STRUCTURE O 34 F THE JAVA VIRTUAL MACHINE

◆ Either the value must be too small (a negative value oflarge magnitude or

negative infinity), and the result is the smallest representable value oftype

int or long.

◆ Or the value must be too large (a positive value of largemagnitude or positive

infinity), and the result is the largest representable value of type int or

long.

A narrowing numeric conversion from double to float behaves in accordance

with IEEE 754. The result is correctly rounded using IEEE 754 round tonearest

mode. A value too small to be represented as a float is converted to apositive or

negative zero of type float; a value too large to be represented as a float is converted

to a positive or negative infinity. A double NaN is alwaysconverted to a

float NaN.

Despite the fact that overflow, underflow, or loss of precision may

occur, narrowing conversions among numeric types never cause the Java

virtual machine to throw a runtime exception (not to be confused with anIEEE

754 floating-pointexception).

1.11.5             ObjectCreation and Manipulation

对象创建和操作指令

Although both class instances and arrays are objects, the Java virtualmachine

creates and manipulates class instances and arrays using distinct sets ofinstructions:

• Create a new class instance: new.

• Create a new array: newarray,anewarray,multianewarray.

• Access fields of classes (static fields, known as class variables) and fields

of class instances (non-static fields, known as instance variables):getfield,

putfield, getstatic,putstatic.

• Load an array component onto the operand stack:baload,caload,saload,

iaload, laload,faload,daload,aaload.

• Store a value from the operand stack as an array component:bastore,castore,

sastore, iastore,lastore,fastore,dastore, aastore.

• Get the length of array: arraylength.

• Check properties ofclass instances or arrays:instanceof,checkcast.

1.11.6             OperandStack Management Instructions

操作数栈管理指令

A number of instructions are provided for the direct manipulation of theoperand

stack: pop, pop2, dup,dup2,dup_x1,dup2_x1, dup_x2, dup2_x2,swap.

1.11.7             ControlTransfer Instructions

控制转换指令

The control transfer instructions conditionally or unconditionally causethe Java virtual

machine to continue execution with an instruction other than the onefollowing

the control transfer instruction. They are:

• Conditional branch: ifeq,iflt,ifle,ifne, ifgt, ifge, ifnull,ifnonnull,if_icmpeq,

if_icmpne, if_icmplt,if_icmpgt,if_icmple,if_icmpge, if_acmpeq, if_acmpne.

• Compound conditional branch: tableswitch, lookupswitch.

• Unconditional branch: goto,goto_w,jsr,jsr_w, ret.

The Java virtual machine has distinct sets of instructions thatconditionally

branch on comparison with data of int and reference types. It also hasdistinct

conditional branch instructions that test for the null reference and thusis not

required to specify a concrete value for null (§2.4).

Conditional branches on comparisons between data of types boolean, byte,

char, and short are performed using int comparisoninstructions (§2.11.1). A

conditional branch on a comparison between data of types long, float, or double

is initiated using an instruction that compares the data and produces an int

result of the comparison (§2.11.3). A subsequent int comparison instructiontests

this result and effects the conditional branch. Because of its emphasis onint

comparisons, the Java virtual machine provides a rich complement ofconditional

branch instructions for type int.

All int conditional controltransfer instructions perform signed comparisons.

1.11.8             MethodInvocation and Return Instructions

方法调用和返回指令

The following five instructions invoke methods:

THE STRUCTURE O 36 F THE JAVA VIRTUAL MACHINE

invokevirtualinvokes an instancemethod of an object, dispatching on the

(virtual) type of the object. This is the normal method dispatch in theJava

programming language.

invokeinterfaceinvokes an interfacemethod, searching the methods implemented

by the particular runtime object to find the appropriate method.

invokespecialinvokes an instancemethod requiring special handling, whether

an instance initialization method (§2.9), a private method, or a superclass

method.

invokestaticinvokes a class (static) method in a namedclass.

invokedynamicinvokes the methodwhich is the target of the call site object

bound to the invokedynamic instruction. The call site object was boundto a

specific lexical occurrence of theinvokedynamicinstruction by theJava virtual

machine as a result of running a bootstrap method before the firstexecution of

the instruction. Therefore, each occurrence of aninvokedynamicinstruction

has a unique linkage state, unlike the other instructions which invokemethods.

The method return instructions, which are distinguished by return type,areireturn

(used to return values of type boolean, byte, char, short, or int),lreturn,freturn,

dreturn, and areturn. In addition, thereturninstruction is used toreturn from

methods declared to be void, instance initialization methods, and class or interface

initializationmethods.

1.11.9             ThrowingExceptions

An exception is thrown programmatically using theathrowinstruction.Exceptions

can also be thrown by various Java virtual machine instructions if theydetect an

1.11.1             Synchronization

同步

The Java virtual machine supports synchronization of both methods andsequences

of instructions within a method by a single synchronization construct: themonitor.

Method-level synchronization is performed implicitly, as part of methodinvocation

and return (§2.11.8). A synchronized method is distinguished in theruntime

constant pool’s method_info structure (§4.6) by the ACC_SYNCHRONIZED

flag, which is checked by the method invocation instructions. Wheninvoking a

method for which ACC_SYNCHRONIZED is set, the executing thread enters amonitor, invokes the method itself, and exits the monitor whether the methodinvocation

completes normally or abruptly. During the time the executing thread owns

the monitor, no other thread may enter it. If an exception is thrownduring invocation

of the synchronized method and the synchronized method does not handle

the exception, the monitor for the method is automatically exited beforethe

exception is rethrown out of the synchronized method.

Synchronization of sequences of instructions is typically used to encodethe

synchronized block of the Java programming language, The Java virtual

machine supplies the monitorenterandmonitorexitinstructions tosupport such

language constructs. Proper implementation of synchronized blocks requires

cooperation from a compiler targeting the Java virtual machine (seeSection 3.14,

“Synchronization”).

Structured locking is the situation when, during a methodinvocation, every

exit on a given monitor matches a preceding entry on that monitor. Sincethere is

no assurance that all code submitted to the Java virtual machine willperform

structured locking, implementations of the Java virtual machine arepermitted but

not required to enforce both of the following two rules guaranteeingstructured

locking. Let T be a thread and M be a monitor. Then:

1. The number of monitor entries performed by T on M during a method invocation

must equal the number of monitor exits performed by T on M during the

method invocation whether the method invocation completes normally or

abruptly.

2. At no point during a method invocation may the number of monitor exitsperformed

by T on M since the methodinvocation exceed the number of monitor

entries performed by T on M since the method invocation.

Note that the monitor entry and exit automatically performed by the Javavirtual

machine when invoking a synchronized method are considered to occur

during the callingmethod’s invocation.

JVM支持方法级和方法内序列结构的同步。通过管程(monitor)来管理。

方法级的同步是隐式的,是在方法调用或者返回中。一个同步的方法在运行时被孤立。

常量池方法信息(method_info)通过ACC_SYNCHRONIZED来标示,用于检测被方法调用的指令,如果调用的方法已经被ACC_SYNCHRONIZED标示过,执行线程进入管程,调用方法,然后退出,管程判断方法是否正常调用完成或者中断。在这其间,执行线程拥有管程,其它线程不的进入。如果一个异常抛出,在同步方法调用其间并且同步方法不能处理这个异常,这个方法的管程原子性退出在异常抛出同步方法之前。

同步指令序列被通常使用java编程语言同步代码块。JVM有monitorenter和monitorexit两种指令来支持这种结构,正确实现同步代码块要求关键需要编译器和JVM合作(cooperation)

结构化锁是指在方法调用其间,每个管程退出都与前面的管程进入相匹配的情景。无法保证所有的代码提交给JVM都满足结构花锁。所以JVM的实现允许但是不强迫通过如下两个规则来保证结构化锁。加入T代表一个线程M代表一个管程。

1、当T执行方法持有管程进入的数量必须和T完成退出(包括方法正常调用完成和中断)释放管程的数量一致。

2、自从方法被调用。在方法调用的任何时刻,都不会存在线程T退出释放M的数量超过(exceed)T持有M的数据,

注意,当调用的同步方法被JVM实施的管程进入和自动释放也是被认为发生在方法调用其间

1.12       ClassLibraries

类库

The Java virtual machine must provide sufficient support for theimplementation of

the class libraries of the associated platform. Some of the classes inthese libraries

cannot be implemented without the cooperation of the Java virtual machine.

Classes that might require special support from the Java virtual machine

JVM必须提供和平台相关联的类库。一些类类库如果脱离了jvm不能被实现。

可能会从JVM中要求一些特殊的支持的类库有:

include those that support:

• Reflection, such as the classes in the package java.lang.reflectand the

class Class.

• Loading and creation of a class or interface. The most obvious exampleis the

class ClassLoader.

• Linking and initialization of a class or interface. The example classescited

above fall into this category as well.

• Security, such as the classes in the package java.security and other classes

such as SecurityManager.

• Multithreading, such as the class Thread.

• Weak references, such as the classes in the package java.lang.ref.

The list above is meant to be illustrative rather than comprehensive. An

exhaustive list of these classes or of the functionality they provide isbeyond the

scope of this book. See the specifications of the Java platform classlibraries for

details.

 

1.13       PublicDesign, Private Implementation

公有设计,私有实现

Thus far this book has sketched the public view of the Java virtualmachine: the

class file format and the instruction set. These components arevital to the hardware-,

operating system-, and implementation-independence of the Java virtual

machine. The implementor may prefer to think of them as a means tosecurely communicate

fragments of programs between hosts each implementing the Java platform,

rather than as a blueprint to be followed exactly.

It is important to understand where the line between the public design andthe

private implementation lies. A Java virtual machine implementation must beable

to read class files and must exactlyimplement the semantics of the Java virtual

machine code therein. One way of doing this is to take this document as aspecification

and to implement that specification literally. But it is also perfectlyfeasible

and desirable for the implementor to modify or optimize the implementation

within the constraints of this specification. So long as the class file format can be

read and the semantics of its code are maintained, the implementor mayimplement

these semantics in any way. What is “under the hood” is the implementor’s

business, as long as the correct external interface is carefullymaintained.

The implementor can use this flexibility to tailor Java virtual machineimplementations

for high performance, low memory use, or portability. What makes

sense in a given implementation depends on the goals of thatimplementation. The

range of implementation options includes the following:

• Translating Java virtual machine code at load time or during executioninto the

instruction set of another virtual machine.

• Translating Java virtual machine code at load time or during executioninto the

native instruction set of the host CPU (sometimes referred to asjust-in-time, or

JIT, code generation).

The existence of a precisely defined virtual machine and object fileformat

need not significantly restrict the creativity of the implementor. TheJava virtual

machine is designed to support many different implementations, providingnew

and interestingsolutions while retaining compatibility between implementations.

本书介绍了JVM公有的部分:class文件格式和指令集合。这些内容对硬件和操心系统以及依赖JVM实现是很重要的。JVM实现者更愿意把他们看做是java平台之间的一种交互片段而多于精准跟随的蓝图。

去理解在公有设计和私有实现之间的分界线是非常重要的。JVM实现者必须有能力读取class文件和必须精准实现jvm中的语义。拿着java虚拟机规范文档逐步实现也是可行的,只要class文件格式能够读取,和代码语义能理解,其中代码的语义能够保持,那么实现者就可以通过任意方法实现这个语义,虚拟机后台如何处理是自己的事情,只要外部接口正确的保持。

Jvm实现者使用伸缩性(flexibility)来让JVM获的高性能(performance)低内存消耗和可移植性(portability)。如何选择取决于实现者的目标。下面有两种实现。

在加载数据时或者执行时转换JVM代码成另外一个jvm指令。

在加载数据时或者执行时转换为本地主机cup指令集合。


原创粉丝点击