沧海一粟

天下事有难易乎?为之,则难者亦易矣;不为,则易者亦难矣。

0%

Java虚拟机结构

The Structure of the Java Virtual Machine

  1. The class File Format
  2. Data Types
  3. Primitive Types and Values
  4. Reference Types and Values
  5. Run-Time Data Areas
  6. Frames
  7. Representation of Objects
  8. Floating-Point Arithmetic
  9. Special Methods
  10. Exceptions
  11. Instruction Set Summary
  12. Class Libraries
  13. Public Design, Private Implementation

  本文档指定了一台抽象机器。它没有描述Java虚拟机的任何特定实现。

  要正确实现Java虚拟机,您只需要能够读取类文件格式并正确执行其中指定的操作。不属于Java虚拟机规范的实现细节将不必要地限制实现者的创造力。例如,运行时数据区域的内存布局、使用的垃圾收集算法以及Java虚拟机指令的任何内部优化(例如,将它们转换为机器代码)都由实现者自行决定。

  本规范中对Unicode的所有引用都是针对Unicode标准6.0.0版提供的,可从http://www.unicode.org/。

this document specifies an abstract machine. It does not describe any particular implementation of the Java Virtual Machine.

To implement the Java Virtual Machine correctly, you need only be able to read the class file format and correctly perform the operations specified therein. Implementation details that are not part of the Java Virtual Machine’s specification would unnecessarily constrain the creativity of implementors. For example, the memory layout of run-time data areas, the garbage-collection algorithm used, and any internal optimization of the Java Virtual Machine instructions (for example, translating them into machine code) are left to the discretion of the implementor.

All references to Unicode in this specification are given with respect to The Unicode Standard, Version 6.0.0, available at http://www.unicode.org/.



(1) 类文件格式 (The class File Format)

  Java虚拟机执行的编译代码使用独立于硬件和操作系统的二进制格式表示,通常(但不一定)存储在一个文件中,称为类文件格式。类文件格式精确地定义了类或接口的表示,包括在特定于平台的对象文件格式中可能被视为理所当然的详细信息。

Compiled code to be executed by the Java Virtual Machine is represented using a hardware- and operating system-independent binary format, typically (but not necessarily) stored in a file, known as the class file format. The class file format precisely defines the representation of a class or interface, including details such as byte ordering that might be taken for granted in a platform-specific object file format.



(2) 数据类型 (Data Types)

  与Java编程语言一样,Java虚拟机操作两种类型:基本类型引用类型 。相应地,有两种值可以存储在变量中,作为参数传递,由方法返回并对其进行操作:原始值和引用值。

  Java虚拟机希望几乎所有类型检查都是在运行时之前完成的,通常是由编译器完成的,而不必由Java虚拟机本身完成。基本类型的值不需要标记,也不需要进行检查,以便在运行时确定它们的类型,或者与引用类型的值区分开来。相反,Java虚拟机的指令集使用旨在对特定类型的值进行操作的指令来区分其操作数类型。例如,iadd、ladd、fadd和dadd都是Java虚拟机指令,它们将两个数值相加并生成数值结果,但每种指令都针对其操作数类型进行了专门化:int、long、float和double。有关Java虚拟机指令集中类型支持的摘要,请参见§2.11.1。

  Java虚拟机包含对对象的显式支持。对象可以是动态分配的类实例或数组。对对象的引用被认为具有Java虚拟机类型引用。类型引用的值可以看作是指向对象的指针。可能存在对一个对象的多个引用。对象总是通过类型引用的值进行操作、传递和测试。

Like the Java programming language, the Java Virtual Machine operates on two kinds of types: primitive types and reference types. There are, correspondingly, two kinds of values that can be stored in variables, passed as arguments, returned by methods, and operated upon: primitive values and reference values.

The Java Virtual Machine expects that nearly all type checking is done prior to run time, typically by a compiler, and does not have to be done by the Java Virtual Machine itself. Values of primitive types need not be tagged or otherwise be inspectable to determine their types at run time, or to be distinguished from values of reference types. Instead, the instruction set of the Java Virtual Machine distinguishes its operand types using instructions intended to operate on values of specific types. For instance, iadd, ladd, fadd, and dadd are all Java Virtual Machine instructions that add two numeric values and produce numeric results, but each is specialized for its operand type: int, long, float, and double, respectively. For a summary of type support in the Java Virtual Machine instruction set, see §2.11.1.

The Java Virtual Machine contains explicit support for objects. An object is either a dynamically allocated class instance or an array. A reference to an object is considered to have Java Virtual Machine type reference. Values of type reference can be thought of as pointers to objects. More than one reference to an object may exist. Objects are always operated on, passed, and tested via values of type reference.



(3) 基本类型和值 (Primitive Types and Values)

  Java虚拟机支持的基本数据类型是 数字类型、布尔类型(§2.3.4)和returnAddress类型(§2.3.3)。
  数字类型包括整数类型(§2.3.1)和浮点类型(§2.3.2)。
    整数类型有:
     byte,其值为8位带符号的两个补码整数,其默认值为零
     short,其值为16位带符号的两个补整数,其默认值为零
     int,其值为32位带符号的两个补整数,其默认值为零
     long,其值为64位带符号的两个补整数,其默认值为零
     char,其值为16位无符号整数,表示基本多语言平面中的Unicode码位,用UTF-16编码,其默认值为空码位(’\u0000’)
    浮点类型包括:
     float,其值是float值集的元素,或者在支持的情况下,是float扩展指数值集的元素,其默认值为正零
     double,其值是double值集的元素,或者在支持的情况下,是double扩展指数值集的元素,其默认值为正零
  布尔类型的值编码真值true和false,默认值为false。

Java®虚拟机规范的第一版没有将boolean视为Java虚拟机类型。但是,布尔值在Java虚拟机中的支持是有限的。Java®虚拟机规范的第二版通过将布尔值作为一种类型来澄清这个问题。

  returnAddress类型的值是指向Java虚拟机指令操作码的指针。在原语类型中,只有returnAddress类型与Java编程语言类型没有直接关联。

(3.1) (Integral Types and Values)

 Java虚拟机的整型值为:

| Integral Types | Values | remark | 两边是否包括在内 |
| byte | -128 ~ 127 | -2^7 ~ 2^7 - 1 | 包括 |
| short | -32768 ~ 32767 | -2^15 ~ 2^15 - 1 | 包括 |
| int | -2147483648 ~ 2147483647 | -2^31 ~ 2^31 - 1 | 包括 |
| long | -9223372036854775808 ~ 9223372036854775807 | -2^63 ~ 2^63 - 1 | 包括 |
| char | 0 ~ 65535 | 0 ~ 2^16 - 1 | 包括 |

3.2. Floating-Point Types, Value Sets, and Values

  浮点类型是float和double,它们在概念上与IEEE二进制浮点运算标准(ANSI/IEEE Std.754-1985,纽约)中规定的32位单精度和64位双精度格式IEEE 754值和操作相关联。

  ieee754标准不仅包括正负号量值,还包括正负零、正负无穷大,以及一个特殊的非数字值(以下简称为“NaN”)。NaN值用于表示某些无效操作(例如零除以零)的结果。

The floating-point types are float and double, which are conceptually associated with the 32-bit single-precision and 64-bit double-precision format IEEE 754 values and operations as specified in IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std. 754-1985, New York).

The IEEE 754 standard includes not only positive and negative sign-magnitude numbers, but also positive and negative zeros, positive and negative infinities, and a special Not-a-Number value (hereafter abbreviated as “NaN”). The NaN value is used to represent the result of certain invalid operations such as dividing zero by zero.

3.3 The returnAddress Type and Values

  returnAddress类型由Java虚拟机的jsr、ret和jsr zu w指令(§jsr、§ret、§jsrĩw)使用。returnAddress类型的值是指向Java虚拟机指令操作码的指针。与数字原语类型不同,returnAddress类型与任何Java编程语言类型都不对应,并且运行的程序无法对其进行修改。

The returnAddress type is used by the Java Virtual Machine’s jsr, ret, and jsr_w instructions (§jsr, §ret, §jsr_w). The values of the returnAddress type are pointers to the 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.

3.4. The boolean Type

  尽管Java虚拟机定义了一个布尔类型,但它只提供非常有限的支持。没有专门用于布尔值操作的Java虚拟机指令。相反,Java编程语言中对布尔值进行操作的表达式被编译为使用Java虚拟机int数据类型的值。

  Java虚拟机直接支持布尔数组。它的newarray指令(§newarray)允许创建布尔数组。使用字节数组指令baload和bastore(§baload,§bastore)访问和修改boolean类型的数组。

  在Oracle的Java虚拟机实现中,Java编程语言中的布尔数组被编码为Java虚拟机字节数组,每个布尔元素使用8位。

  Java虚拟机对布尔数组组件进行编码,使用1表示真,0表示假。当编译器将Java编程语言布尔值映射到Java虚拟机类型int的值时,编译器必须使用相同的编码。

Although the Java Virtual Machine defines a boolean type, it only provides very limited support for it. There are no Java Virtual Machine instructions solely 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. Its newarray instruction (§newarray) enables creation of boolean arrays. Arrays of type boolean are accessed and modified using the byte array instructions baload and bastore (§baload, §bastore).

In Oracle’s Java Virtual Machine implementation, boolean arrays in the Java programming language are encoded as Java Virtual Machine byte arrays, using 8 bits per boolean element.

The Java Virtual Machine encodes boolean array components using 1 to represent true and 0 to represent false. Where Java program



4. 引用类型和值 ( Reference Types and Values )

有三种引用类型:类类型,数组类型和接口类型。它们的值分别引用动态创建的类实例,数组或实现接口的类实例或数组。

数组类型由具有单个维度的组件类型组成(其长度未由类型指定)。数组类型的组件类型本身可以是数组类型。如果从任何数组类型开始,先考虑其组件类型,然后再考虑(如果也是数组类型)该类型的组件类型,依此类推,则最终必须达到不是数组类型的组件类型;这称为数组类型的元素类型。数组类型的元素类型必须是原始类型,类类型或接口类型。

引用值也可以是特殊的空引用,即无对象的引用,此处将以空表示。空引用最初没有运行时类型,但可以强制转换为任何类型。引用类型的默认值为null。

本规范不要求编码为null的具体值。

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 may itself be an array type. If, starting from any array type, one considers its component 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; this is called the element type of the array type. The element 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 the special null reference, a reference to no object, which will be denoted here by null. The null reference initially has no run-time type, but may be cast to any type. The default value of a reference type is null.

This specification does not mandate a concrete value encoding null.


5. 运行时数据区域 ( Run-Time Data Areas )

5.1 pc计数器 ( The pc Register )

Java虚拟机同一时刻可以支持许多执行线程。 每个Java虚拟机线程都有其自己的pc(程序计数器)寄存器。 在任何时候,每个Java虚拟机线程都在执行单个方法的代码,即该线程的当前方法。 如果该方法不是native方法,则pc寄存器包含当前正在执行的Java虚拟机指令的地址。 如果线程当前正在执行的方法是native方法,则Java虚拟机的pc寄存器的值是undefined。 Java虚拟机的pc寄存器足够宽,可以在特定平台上保存returnAddress或本机指针。

The Java Virtual Machine can support many threads of execution at once . 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 single method, namely the current method for that thread. If that method is not native, the pc register contains the address of the Java Virtual Machine instruction 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 wide enough to hold a returnAddress or a native pointer on the specific platform.

5.2 JVM栈 Java Virtual Machine Stacks

Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread. A Java Virtual Machine stack stores frames . A Java Virtual Machine stack is analogous to the stack of a conventional language such as C: it holds local variables and partial results, and plays a part in method invocation and return. Because the Java Virtual Machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java Virtual Machine stack does not need to be contiguous.

In the First Edition of The Java® Virtual Machine Specification, the Java Virtual Machine stack was known as the Java stack.

This specification permits Java Virtual Machine stacks either to be of a fixed size or to dynamically expand and contract as required 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 that stack is created.

A Java Virtual Machine implementation may provide the programmer or the user control over the initial size of Java Virtual Machine stacks, as well as, in the case of dynamically expanding or contracting Java Virtual Machine stacks, 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 Machine stack than is permitted, the Java Virtual Machine throws a StackOverflowError.

If Java Virtual Machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, 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.

References

[1] Chapter 2. The Structure of the Java Virtual Machine
[2] Chapter 2. The Structure of the Java Virtual Machine