Java虚拟机结构原文:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html
This document specifies an abstract machine. It does not describe any particular implementation of the Java Virtual Machine. 该文件指定了抽象机。它没有描述Java任何具体的虚拟机实现。
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. 要正确实现Java Virtual Machine,您只需要能够读取类文件格式并正确执行指定的操作。不属于Java Virtual Machine实现规范的细节将不必要地限制实现者的创造力。例如,运行时数据区域的内存布局、使用的垃圾收集算法和Java Virtual Machine任何内部优化(例如,将其转换为机器代码)都由实现者决定。 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/. 本规范中对Unicode所有参考都是关于的Unicode标准,版本6.0.0,可在http://www.unicode.org/获得。
2.1. The class File Format 类文件格式
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. 由Java虚拟机执行的编译代码使用独立于硬件和操作系统的二进制格式,通常(但不一定)存储在文件中,称为类别文件格式。类别文件格式准确地定义了类别或接口的表示,包括字节排序等细节,这可能被认为是平台上特定对象文件格式的理所当然。
Chapter 4, “The class File Format”, covers the class file format in detail. 第四章类文件格式详细介绍了类文件格式。
2.2. Data Types 数据类型
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. 与Java编程语言一样,Java虚拟机操作有两种类型:基本类型和引用类型。因此,有两个值可以存储在变量中作为参数传输,通过方法返回并操作:。
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. Java虚拟机期望几乎所有的虚拟机的,通常,而不必由Java虚拟机本身就完成了。基本类型的值不需要标记,也不需要通过检查来确定它们在运行过程中的类型,或区分引用类型的值。。例如,iadd、ladd、fadd和dadd都是Java虚拟机指令用于将两个值相加并产生数值结果,但每个指令都针对其操作数类型:int、long、float和double。关于Java请参考虚拟机指令集中类型支持的总结§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. Java虚拟机包含对象的显式支持。对象可以是动态分配的类实例或数组。对象的引用被认为是可用的Java引用虚拟机类型。。。。
2.3. Primitive Types and Values 基本类型和值
The primitive data types supported by the Java Virtual Machine are the numeric types, the boolean type (§2.3.4), and the returnAddress type (§2.3.3). Java虚拟机支持(§2.3.3)。
The numeric types consist of the integral types (§2.3.1) and the floating-point tpes (§2.3.2). 数值类型包括整型(§2.3.1)和浮点型(§2.3.2)。
The integral types are: 整型有:
-
byte, whose values are 8-bit signed two’s-complement integers, and whose default value is zero Byte,其值为8位有符号的二进制整数,默认值为0
-
short, whose values are 16-bit signed two’s-complement integers, and whose default value is zero Short,其值为16位有符号的二进制整数,默认值为0
-
int, whose values are 32-bit signed two’s-complement integers, and whose default value is zero Int,其值为32位有符号的二进制整数,默认值为0
-
long, whose values are 64-bit signed two’s-complement integers, and whose default value is zero Long,其值为64位有符号的二进制整数,默认值为0
-
char, whose values are 16-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’) Char,其值为16位整数,表示基于多语言的Unicode码位,使用UTF-16编码,其默认值为空码位(‘\u0000’) The floating-point types are:
-
float, whose values are elements of the float value set or, where supported, the float-extended-exponent value set, and whose default value is positive zero 浮点数,其值是浮点值集的元素,或者(在支持的情况下)浮点扩展指数值集的元素,其默认值为正零
-
double, whose values are elements of the double value set or, where supported, the double-extended-exponent value set, and whose default value is positive zero Double,其值为双精度值集的元素,在支持的情况下为双扩展指数值集的元素,其默认值为正零
The values of the boolean type encode the truth values true and false, and the default value is false. 布尔类型的值编码为真值true和false,默认值为false。
The First Edition of The Java® Virtual Machine Specification did not consider boolean to be a Java Virtual Machine type. However, boolean values do have limited support in the Java Virtual Machine. The Second Edition of The Java® Virtual Machine Specification clarified the issue by treating boolean as a type. Java®虚拟机规范的第一版没有将布尔值视为Java虚拟机类型。但是,布尔值在Java虚拟机中支持有限。Java®虚拟机规范的第二版通过将布尔值作为一种类型来澄清这个问题。
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 directly associated with a Java programming language type. 。在基本类型中,只有returnAddress类型与Java编程语言类型没有直接关联。
2.3.1. Integral Types and Values 整型和值
The values of the integral types of the Java Virtual Machine are:
-
For byte, from -128 to 127 (-2^7 to 2^7 - 1), inclusive
-
For short, from -32768 to 32767 (-2^15 to 2^15 - 1), inclusive
-
For int, from -2147483648 to 2147483647 (-2^31 to 2^31 - 1), inclusive
-
For long, from -9223372036854775808 to 9223372036854775807 (-2^63 to 2^63 - 1), inclusive
-
For char, from 0 to 65535 inclusive
2.3.2. Floating-Point Types, Value Sets, and Values 浮点类型、值集和值
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). 浮点类型是float和double,它们在概念上与IEEE二进制浮点算术标准(ANSI/IEEE Std. 754-1985,纽约)中规定的32位单精度和64位双精度格式IEEE 754值和操作相关联。
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. IEEE 754标准不仅包括正负符号数量级,还包括正负零、正负无穷以及特殊的非a- number值(以下简称“NaN”)。NaN值用于表示某些无效操作的结果,例如0除以0。
Every implementation of the Java Virtual Machine is required to support two standard sets of floating-point values, called the float value set and the double value set. In addition, an implementation of the Java Virtual Machine may, at its option, support either or both of two extended-exponent floating-point value sets, called the float-extended-exponent value set and the double-extended-exponent value set. These extended-exponent value sets may, under certain circumstances, be used instead of the standard value sets to represent the values of type float or double. Java Virtual Machine的每个实现都需要支持两个标准的浮点值集,称为浮点值集和双值集。此外,Java虚拟机的实现可以选择支持两个扩展指数浮点值集中的一个或两个,称为浮点扩展指数值集和双扩展指数值集。在某些情况下,可以使用这些扩展指数值集代替标准值集来表示float或double类型的值。
The finite nonzero values of any floating-point value set can all be expressed in the form s ⋅ m ⋅ 2(e − N + 1), where s is +1 or −1, m is a positive integer less than 2N, and e is an integer between Emin = −(2K−1−2) and Emax = 2K−1−1, inclusive, and where N and K are parameters that depend on the value set. 任意浮点值集的有限非零值都可以用s⋅m⋅2(e−N +1)的形式表示,其中s为+1或−1,m为小于2N的正整数,e为Emin =−(2K−1−2)和Emax = 2K−1−1之间的整数,其中N和K为依赖于值集的参数。 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 using certain values for s, m, and e, then if it happened that m were even and e were less than 2K-1, one could halve m and increase e by 1 to produce a second representation for the same value v. A representation in this form is called normalized if m ≥ 2N-1; 有些值可以用一种以上的方式表示;例如,假设值集中的一个值v可以用s、m和e的特定值以这种形式表示,那么如果m是偶数且e小于2K-1,人们可以将m减半并将e增加1来产生相同值v的第二种表示。如果m≥2N-1,这种形式的表示被称为;otherwise the representation is said to be denormalized. If a value in a value set cannot be represented in such a way that m ≥ 2N-1, then the value is said to be a denormalized value, because it has no normalized representation.否则,该表示被称为非规范化。如果一个值集中的一个值不能以m≥2N-1的方式表示,那么这个值被称为非规范化值,因为它没有规范化表示。
The constraints on the parameters N and K (and on the derived parameters Emin and Emax) for the two required and two optional floating-point value sets are summarized in Table 2.3.2-A. 表2.3.2-A总结了两个必需的和两个可选的浮点值集的参数N和K(以及派生参数Emin和Emax)的约束。
Where one or both extended-exponent value sets are supported by an implementation, then for each supported extended-exponent value set there is a specific implementation-dependent constant K, whose value is constrained by Table 2.3.2-A; this value K in turn dictates the values for Emin and Emax.当一个实现支持一个或两个扩展指数值集时,那么对于每个受支持的扩展指数值集,都有一个特定的与实现相关的常数K,其值受表2.3.2-A的约束;这个值K又决定了Emin和Emax的值。
Each of the four value sets includes not only the finite nonzero values that are ascribed to it above, but also the five values positive zero, negative zero, positive infinity, negative infinity, and NaN. 这四个值集中的每一个不仅包括上面赋予它的有限非零值,还包括
Note that the constraints in Table 2.3.2-A are designed so that every element of the float value set is necessarily also an element of the float-extended-exponent value set, the double value set, and the double-extended-exponent value set. 注意,表2.3.2-A中的约束条件是这样设计的:。Likewise, each element of the double value set is necessarily also an element of the double-extended-exponent value set. Each extended-exponent value set has a larger range of exponent values than the corresponding standard value set, but does not have more precision.同样,。每个扩展指数值集比对应的标准值集具有更大的指数值范围,但并不具有更高的精度。
The elements of the float value set are exactly the values that can be represented 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). (IEEE 754指定了224-2个不同的NaN值)。The elements of the double value set are exactly the values that can be represented using the double floating-point format defined in the IEEE 754 standard, except that there is only one NaN value (IEEE 754 specifies 253-2 distinct NaN values). (IEEE 754指定了253-2个不同的NaN值)。Note, however, that the elements of the float-extended-exponent and double-extended-exponent value sets defined here do not correspond to the values that can be represented using IEEE 754 single extended and double extended formats, respectively.但是请注意,这里定义的浮点扩展指数和双扩展指数值集的元素分别使用IEEE 754单扩展和双扩展格式表示的值。 This specification does not mandate a specific representation for the values of the floating-point value sets except where floating-point values must be represented in the class file format (§4.4.4, §4.4.5).本规范没有规定浮点值集合的值的具体表示,除非浮点值必须用类文件格式表示(§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 of the Java Virtual Machine to use an element of the float value set to represent a value of type float;。Java虚拟机的实现使用float值集的元素来表示float类型的值总是正确的; however, it may be permissible in certain contexts for an 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 value set to represent a value of type double; however, it may be permissible in certain contexts for an implementation to use an element of the double-extended-exponent value set instead.但是,在某些上下文中,可能允许实现使用浮点扩展指数值集的元素。类似地,实现中使用双精度值集的元素来表示双精度类型的值总是正确的;但是,在某些上下文中,可能允许实现使用双扩展指数值集的元素。
Except for NaNs, values of the floating-point value sets are ordered. When arranged from smallest to largest, they are negative infinity, negative finite values, positive and negative zero, positive finite values, and positive infinity. 除 NaN外,浮点值集的值是有序的。当从最小到最大排列时,它们是。
Floating-point positive zero and floating-point negative zero compare as equal, but there are other operations that can distinguish them; for example, dividing 1.0 by 0.0 produces positive infinity, but dividing 1.0 by -0.0 produces negative infinity. 。
0.0==-0.0 => true
1.0/0.0 => Infinity
1.0/-0.0 => -Infinity
NaNs are unordered, so numerical comparisons and tests for numerical equality have the value false if either or both of their operands are NaN. In particular, 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,则值为false。特别是,当且仅当值为NaN时,测试值与自身的数值相等时,该值为false。如果任意一个操作数为NaN,则数值不等式的测试值为true。
// 返回false
Double.NaN == Double.NaN
NaN = 0.0f / 0.0f
NaN = 0.0d / 0.0
2.3.3. The returnAddress Type and Values returnAddress类型和值
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. returnAddress类型被Java虚拟机的jsr、ret和jsr_w指令(§jsr、§ret、§jsr_w)使用。returnAddress类型的值是指向Java虚拟机指令操作码的指针。与数字原语类型不同,。
2.3.4. The boolean Type 布尔类型
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. 尽管Java Virtual Machine定义了布尔类型,但它只提供了非常有限的支持。没有专门用于布尔值操作的Java虚拟机指令。相反,Java编程语言中对布尔值进行操作的表达式被编译为使用Java Virtual Machine int数据类型的值。
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. 在Oracle的Java虚拟机实现中,Java编程语言中的布尔数组被编码为Java虚拟机字节数组,每个布尔元素使用8位。
The Java Virtual Machine encodes boolean array components using 1 to 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. Java虚拟机对布尔数组组件进行编码,。当Java编程语言的布尔值被编译器映射到Java虚拟机类型int的值时,编译器必须使用相同的编码。
2.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 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. 引用值也可以是特殊的空引用,即对任何对象的引用,这里用null表示。。。
This specification does not mandate a concrete value encoding null. 此规范不要求将具体值编码为空。
2.5. Run-Time Data Areas 运行时数据区
The Java Virtual Machine defines various run-time data areas that are used during execution of a program. Some of these data areas are created on Java Virtual Machine start-up and are destroyed only when the Java Virtual Machine exits. Other data areas are per thread. Per-thread data areas are created when a thread is created and destroyed when the thread exits. Java虚拟机定义了在程序执行期间使用的各种运行时数据区域。其中是在Java Virtual Machine启动时创建的,只有在Java Virtual Machine退出时才会销毁。。 。
2.5.1. The pc Register 程序计数器
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. Java虚拟机可以支持多个线程同时执行(JLS§17)。。 At any point, each Java Virtual Machine thread is executing the code of a single method, namely the current method (§2.6) for that thread. 在任何时候,每个Java虚拟机线程都在执行单个方法的代码,即该线程的当前方法(§2.6)。 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. Java虚拟机的pc寄存器足够宽,可以容纳特定平台上的returnAddress或本机指针。
2.5.2. Java Virtual Machine Stacks Java虚拟机栈
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 (§2.6). 。Java虚拟机栈存储帧(§2.6)。 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. Java虚拟机堆栈类似于传统语言(如C语言)的堆栈:它保存局部变量和部分结果,并在方法调用和返回中发挥作用。 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. 因为除了push和pop帧外,Java Virtual Machine堆栈永远不会被直接操作,所以。Java虚拟机堆栈的内存不需要是连续的。
In the First Edition of The Java® Virtual Machine Specification, the Java Virtual Machine stack was known as the Java stack. 在Java®虚拟机规范的第一版中,Java虚拟机栈被称为Java栈。
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. 该规范允许Java Virtual Machine堆栈具有固定的大小,或者根据计算的需要动态地展开和收缩。如果Java虚拟机堆栈的大小是固定的,那么在创建每个Java虚拟机堆栈时,可以独立选择该堆栈的大小。
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. Java虚拟机实现可以让程序员或用户控制Java虚拟机堆栈的初始大小,在动态扩展或收缩Java虚拟机堆栈的情况下,还可以控制最大和最小大小。
The following exceptional conditions are associated with Java Virtual Machine stacks: 以下异常情况与Java虚拟机栈相关:
-
If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws a StackOverflowError. 如果线程中的计算需要比允许的更大的Java Virtual Machine堆栈,Java Virtual Machine将抛出。
-
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. 如果可以动态扩展Java Virtual Machine堆栈,并且尝试进行扩展,但可能会提供不足的内存来影响扩展,或者如果可以提供不足的内存来为新线程创建初始Java Virtual Machine堆栈,Java Virtual Machine会抛出一个。
2.5.3. Heap 堆
The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated. Java虚拟机有一个堆,在所有Java虚拟机线程之间。,所有类实例和数组的内存都从这里分配。
The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); 。对象的堆存储由自动存储管理系统(称为垃圾收集器)回收; objects are never explicitly deallocated.。 The Java Virtual Machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor’s system requirements. Java虚拟机没有采用特定类型的自动存储管理系统,可以根据实现者的系统需求选择存储管理技术。 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 heap can be dynamically expanded or contracted, control over the maximum and minimum heap size. Java Virtual Machine实现可以让程序员或用户控制堆的初始大小,如果可以动态扩展或收缩堆,还可以控制堆的最大和最小大小。 The following exceptional condition is associated with the heap: 下面是与堆相关的异常条件:
- If a computation requires more heap than can be made available by the automatic storage management system, the Java Virtual Machine throws an OutOfMemoryError. 如果计算需要比自动存储管理系统所能提供的更多的堆,Java Virtual Machine就会抛出一个。
2.5.4. Method Area 方法区
The Java Virtual Machine has a method area that is shared among all Java Virtual Machine threads. Java虚拟机有一个在所有Java虚拟机线程之间的方法区域。 The method area is analogous to the storage area for compiled code of a conventional language or analogous to the “text” segment in an operating system process. 方法区域类似于传统语言的编译代码的存储区域,或类似于操作系统进程中的“文本”段。 It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization. 它存储每个类的结构,如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括在类和实例初始化和接口初始化中使用的特殊方法(§2.9)。
The method area is created on virtual machine start-up. 。 Although the method area is logically part of the heap, simple implementations may choose not to either garbage collect or compact it. This specification does not mandate the location of the method area or the policies used to manage 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 method area becomes unnecessary. The memory for the method area 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 method area, as well as, in the case of a varying-size method area, control over the maximum and minimum method area size. Java虚拟机实现可以让程序员或用户控制方法区域的初始大小,在方法区域大小可变的情况下,还可以控制方法区域的最大和最小大小。 The following exceptional condition is associated with the method area: 与方法区域相关的异常情况如下:
- If memory in the method area cannot be made available to satisfy an allocation request, the Java Virtual Machine throws an . 如果方法区域中的内存不能满足分配请求,Java虚拟机就会抛出一个OutOfMemoryError。
2.5.5. Run-Time Constant Pool 运行时常量池
A run-time constant pool is a per-class or per-interface run-time representation of the constant_pool table in a class file (§4.4). (§4.4)。 It contains several kinds of constants, ranging from numeric literals known at compile-time to method and field references that must be resolved at run-time. 它包含几种类型的常量,从编译时已知的数值文字到必须在运行时解析的方法和字段引用。 The run-time constant pool serves a function 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 run-time constant pool is allocated from the Java Virtual Machine’s method area (§2.5.4). The run-time constant pool for a class or interface is constructed when the class or interface is created (§5.3) by the Java Virtual Machine. (§2.5.4)。(§5.3)。 The following exceptional condition is associated with the construction of the run-time constant pool for a class or interface: 以下异常条件与类或接口的运行时常量池的构造相关:
- When creating a class or interface, if the construction of the run-time constant pool requires more memory than can be made available in the method area of the Java Virtual Machine, the Java Virtual Machine throws an OutOfMemoryError. See §5 (Loading, Linking, and Initializing) for information about the construction of the run-time constant pool. 关于运行时常量池的构造,请参见§5(加载、链接和初始化)。
2.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). Java虚拟机的实现可以使用传统的栈,通俗地称为“”,以支持本地方法(用Java编程语言以外的语言编写的方法)。 Native method stacks may also be used by the implementation of an interpreter for the Java Virtual Machine’s instruction set in a language such as C. Java Virtual Machine implementations that cannot load native methods and that do not themselves rely on conventional stacks need not supply native method stacks. If supplied, native method stacks are typically allocated per thread when each thread is created. ,例如c语言。Java虚拟机实现如果不能加载本地方法,并且本身不依赖于传统的栈,就不需要提供本地方法栈。如果提供本地方法栈,则通常在。 This specification permits native method stacks either to be of a fixed size or to dynamically expand and contract as required by the 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. 该规范允许本地方法栈具有固定的大小,或者根据计算的需要动态地展开和收缩。如果本地方法堆栈的大小是固定的,则每个本地方法堆栈的大小可以在创建该堆栈时独立选择。 A Java Virtual Machine implementation may provide the programmer or the user control over the initial size of the native method stacks, as well as, in the case of varying-size native method stacks, control over the maximum and minimum method stack sizes. Java虚拟机实现可以让程序员或用户控制本地方法堆栈的初始大小,在本地方法堆栈大小可变的情况下,还可以控制方法堆栈的最大和最小大小。 The following exceptional conditions are associated with native method stacks: 以下异常条件与本地方法栈相关:
- If the computation in a thread requires a larger native method stack than is permitted, the Java Virtual Machine throws a 如果线程中的计算需要比允许的更大的本地方法堆栈,Java虚拟机将抛出StackOverflowError。
- If native method stacks can be dynamically expanded and native method stack expansion is attempted but insufficient memory can be made available, or if insufficient memory can be made available to create the initial native method stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError. 如果可以动态扩展本地方法堆栈,并且尝试进行本地方法堆栈扩展,但可能会提供不足的内存,或者如果为新线程创建初始本地方法堆栈提供了不足的内存,Java虚拟机将抛出OutOfMemoryError。
2.6. Frames 栈帧
A frame is used to store data and 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 or abrupt (it throws an uncaught exception). 当它的,无论这个完成是正常的还是突然的(它会抛出一个未捕获的异常)。 Frames are allocated from the Java Virtual Machine stack (§2.5.2) of the thread creating the frame. Each frame has its own array of local variables (§2.6.1), its own operand stack (§2.6.2), and a reference to the run-time constant pool (§2.5.5) of the class of the current method. 。每一帧都有自己的(§2.6.1),自己的(§2.6.2),以及对当前方法(§2.5.5)。 A frame may be extended with additional implementation-specific information, such as debugging information. 可以使用附加的实现特定信息(如调试信息)对栈帧进行扩展。 The sizes of the local variable array and the operand stack are determined at compile-time and are supplied along with the code for the method associated with the frame (§4.7.3). ,并与栈帧相关的方法代码一起提供(§4.7.3)。 Thus the size of the frame data structure depends only on the implementation of the Java Virtual Machine, and the memory for these structures can be allocated simultaneously on method invocation. 因此,栈帧数据结构的大小仅取决于Java虚拟机的实现,可以在方法调用时同时分配用于这些结构的内存。 Only one frame, the frame for the executing method, is active at any point in a given thread of control. This frame is referred to as the current frame, 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 the operand stack are typically with reference to the current frame. 在给定的控制线程中,只有一个帧(即执行方法的帧)是活动的。 这个栈帧被称为,它的方法被称为。定义当前方法的类就是。。 A frame ceases to be current if its method invokes another method or if its method completes. When a method is invoked, a new frame is created and becomes current when control transfers to the new method. 如果它的方法调用了另一个方法或者它的方法完成了,那么这个栈帧就不再是当前的。当调用方法时,将创建一个新栈帧,并在控制转移到新方法时成为当前栈帧。 On method return, the current frame passes back the result of its method invocation, if any, to the previous frame. The current frame is then discarded as the previous frame becomes the current one. 在方法返回时,。当前一帧变成当前帧时,当前帧就会被丢弃。 Note that a frame created by a thread is local to that thread and cannot be referenced by any other thread. 。
2.6.1. Local Variables 局部变量
Each frame (§2.6) contains an array of variables known as its local variables. The length of the local variable array of a frame is determined at compile-time and supplied in the binary representation of a class or interface along with the code for the method associated with the frame (§4.7.3). 每一帧(§2.6)包含一个变量数组,称为。,同时提供与该帧相关的方法代码(§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. 一个局部变量可以保存boolean、byte、char、short、int、float、reference或returnAddress类型的值。一对局部变量可以保存long或double类型的值(long何double类型占用两个局部变量)。 Local variables are addressed by indexing. The index of the first local variable is zero. An integer is considered to be an index into the local variable array if and only if that integer is between zero and one less than the size of the local 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 index n actually occupies the local variables with indices n and n+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. 。这样的值。例如,存储在索引为n的局部变量数组中的double类型的值实际上会占用索引为n和n+1的局部变量;但是,不能从索引n+1处加载局部变量。它可以被储存。但是,这样做会使局部变量n的内容无效。 The Java Virtual Machine does not require n to be even. In intuitive terms, values of types long and double need not be 64-bit aligned in the local variables array. Implementors are free to decide the appropriate way to represent such values using the two local variables reserved for the value. Java虚拟机不需要n为偶数。直观地说,。实现者可以使用为该值保留的两个局部变量自由决定表示这些值的适当方式。 The Java Virtual Machine uses local variables to pass parameters on method invocation. On class method invocation, any parameters are passed in consecutive local variables starting from local variable 0. On instance method invocation, local variable 0 is always used to pass a reference to the object on which the instance method is being invoked (this in the Java programming language). Any parameters are subsequently passed in consecutive local variables starting from local variable 1. Java虚拟机使用局部变量在方法调用时传递参数。在类方法调用中,。在实例方法调用时,总是使用局部变量0向调用实例方法的对象传递引用(这在Java编程语言中是这样的)。任何参数随后在从局部变量1开始的连续局部变量中传递。
2.6.2. Operand Stacks 操作数栈
Each frame (§2.6) contains a last-in-first-out (LIFO) stack known as its operand stack. The maximum depth of the operand stack of a frame is determined at compile-time and is supplied along with the code for the method associated with the frame (§4.7.3). 每一帧(§2.6)包含一个,即其。,并与该帧相关的方法代码一起提供(§4.7.3)。 Where it is clear by context, we will sometimes refer to the operand stack of 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 values from local variables or fields onto the operand stack. Other Java Virtual Machine instructions take operands from the operand stack, operate on them, and push the result back onto the operand stack. The operand stack is also used to prepare parameters to be passed to methods and to receive method results. ,。。其他Java虚拟机指令从操作数堆栈中获取操作数,对它们进行操作,然后将结果压回操作数堆栈。。 For example, the iadd instruction (§iadd) adds two int values together. It requires that the int values to be added be the top two values of the operand stack, pushed there by previous instructions. Both of the int values are popped from the operand stack. They are added, and their sum is pushed back onto the operand stack. Subcomputations may be nested on the operand stack, resulting in values that can be used by the encompassing computation. 例如,iadd指令(§iadd)将两个int值相加。它要求要添加的int值是操作数堆栈的前两个值,由前面的指令推送到那里。两个int值都是从操作数堆栈中弹出的。它们被添加,它们的和被推回操作数堆栈。子计算可以嵌套在操作数堆栈上,从而得到可由包含计算使用的值。 Each entry on the operand stack can hold a value of any Java Virtual Machine 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 and subsequently 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 Machine instructions (the dup instructions (§dup) and swap (§swap)) operate on run-time data areas as raw values without regard to their specific types; these instructions are defined in such a way that they cannot be used to modify or break up individual values. These restrictions on operand stack manipulation are enforced through class file verification (§4.10). 。例如,不可能推送两个int值并随后将其视为long值,也不可能推送两个float值并随后使用iadd指令将其添加。少量的Java虚拟机指令(dup指令(§dup)和swap指令(§swap))以原始值的形式操作运行时数据区域,而不考虑它们的特定类型; 这些指令的定义方式是这样的,它们不能用来修改或拆分单独的值。 这些对操作数堆栈操作的限制是通过类文件验证来实施的(§4.10)。 At any point in time, an operand stack has an associated depth, where a value of type long or double contributes two units to the depth and a value of any other type contributes one unit. 在任何时间点,操作数堆栈都有一个相关联的深度,其中long或double类型的值为深度贡献两个单位,任何其他类型的值为深度贡献一个单位。
2.6.3. Dynamic Linking 动态链接
Each frame (§2.6) contains a reference to the run-time constant pool (§2.5.5) for the type of the current method to support dynamic linking of the method code. The class file code for a method refers to methods to be invoked and variables to be accessed via symbolic references. Dynamic linking translates these symbolic method references into concrete method references, loading classes as necessary to resolve as-yet-undefined symbols, and translates variable accesses into appropriate offsets in storage structures associated with the run-time location of these variables. 每一帧(§2.6)都包含对当前方法类型的运行时常量池(§2.5.5)的引用,以支持方法代码的。方法的类文件代码通过符号引用引用要调用的方法和要访问的变量。 动态链接将这些,根据需要加载类来解析尚未定义的符号,并将变量访问转换为与这些变量的运行时位置相关的存储结构中的适当。 This late binding of the methods and variables makes changes in other classes that a method uses less likely to break this code. 。
2.6.4. Normal Method Invocation Completion 程序运行正常的返回处理
A method invocation completes normally if that invocation does not cause an exception (§2.10) to be thrown, either directly from the Java Virtual Machine or as a result of executing an explicit throw statement. 如果方法调用没有直接从Java虚拟机或执行显式抛出语句引发异常(§2.10),那么方法调用将。 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 being returned (if any). 如果当前方法的调用正常完成,那么可能会向调用方法返回一个值。当被调用的方法执行一个返回指令(§2.11.8)时,就会发生这种情况,。 The current frame (§2.6) is used in this case to restore the state of the invoker, including its local variables and operand stack, with the program counter of the invoker appropriately incremented to skip past the method invocation instruction. Execution then continues normally in the invoking method’s frame with the returned value (if any) pushed onto the operand stack of that frame. 在这种情况下,使用当前栈帧(§2.6)来恢复调用者的状态,包括它的局部变量和操作数堆栈,并适当。然后在调用方法的帧中继续正常执行,。
2.6.5. Abrupt Method Invocation Completion 程序运行异常的返回处理逻辑
A method invocation completes abruptly if execution of a Java Virtual Machine instruction within the method causes the Java Virtual Machine to throw an exception (§2.10), and that exception is not handled within the method. Execution of an athrow instruction (§athrow) also causes an exception to be explicitly thrown and, if the exception is not caught by the current method, results in abrupt method invocation completion. A method invocation that completes abruptly never returns a value to its invoker. 如果在方法中执行Java虚拟机指令导致Java虚拟机(§2.10),而该异常不在方法中处理,那么方法调用就会突然结束。执行throw指令(§throw)也会导致显式抛出异常,如果当前方法没有捕捉到异常,则会导致方法调用突然完成。。
2.7. Representation of Objects 对象表达
The Java Virtual Machine does not mandate any particular internal structure for objects. Java虚拟机不强制要求任何特定的对象内部结构。 In some of Oracle’s implementations of the Java Virtual Machine, a reference to a class instance is a pointer to a handle that is itself a pair of pointers: one to a table containing the methods of the object and a pointer to the Class object that represents the type of the object, and the other to the memory allocated from the heap for the object data. 在Oracle对Java虚拟机的一些实现中,。
2.8. Floating-Point Arithmetic 浮点运算法
The Java Virtual Machine incorporates a subset of the floating-point arithmetic specified in IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std. 754-1985, New York). Java虚拟机包含了IEEE二进制浮点算术标准(ANSI/IEEE Std. 754-1985,纽约)中指定的浮点算术子集。
2.8.1. Java Virtual Machine Floating-Point Arithmetic and IEEE 754 Java虚拟机浮点运算与IEEE 754
The key differences between the floating-point arithmetic supported by the Java Virtual Machine and the IEEE 754 standard are: Java虚拟机支持的浮点运算与IEEE 754标准之间的是:
-
The floating-point operations of the Java Virtual Machine do not throw exceptions, trap, or otherwise signal the IEEE 754 exceptional conditions of invalid operation, division by zero, overflow, underflow, or inexact. The Java Virtual Machine has no signaling NaN value. Java虚拟机的浮点操作不会抛出异常、陷阱或发出无效操作、除零、溢出、下溢或不精确的IEEE 754异常条件信号。Java虚拟机使用无信号的NaN值。
-
The Java Virtual Machine does not support IEEE 754 signaling floating-point comparisons. Java虚