Java8虚拟机的结构

4 篇文章 0 订阅

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虚拟机本身完成。基本类型的值不需要进行标记,也不需要通过检查来确定它们在运行时的类型,或者与引用类型的值区分开来。相反,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.4)和returnAddress类型(§2.3.3)。

The numeric types consist of the integral types (§2.3.1) and the floating-point types (§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虚拟机指令操作码的指针。在基本类型中,只有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.
这四个值集中的每一个不仅包括上面赋予它的有限非零值,还包括正零、负零、正无穷、负无穷和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). float值集的元素正是可以使用IEEE 754标准中定义的单浮点格式表示的值,只是只有一个NaN值(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标准中定义的双浮点格式表示的值,只是只有一个NaN值(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.
浮点正零和浮点负零的比较是相等的,但还有其他操作可以区分它们;例如,用1.0除以0.0得到正无穷,但用1.0除以-0.0得到负无穷

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虚拟机指令操作码的指针。与数字原语类型不同,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).
Java虚拟机直接支持布尔数组。它的newarray指令(§newarray)允许创建布尔数组。使用字节数组指令baload和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虚拟机对布尔数组组件进行编码,使用1表示真,0表示假。当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表示。空引用最初没有运行时类型,但可以强制转换为任何类型引用类型的默认值为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)。每个Java虚拟机线程都有自己的pc(程序计数器)寄存器
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.
如果不是本地方法,那么pc寄存器包含当前正在执行的Java虚拟机指令的地址
If the method currently being executed by the thread is native, the value of the Java Virtual Machine’s pc register is undefined.
如果当前被线程执行的方法是本地方法,那么Java虚拟机的pc寄存器的值是未定义的。
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 Virtual Machine线程都有一个私有的Java Virtual Machine堆栈,与线程同时创建。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将抛出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.
    如果可以动态扩展Java Virtual Machine堆栈,并且尝试进行扩展,但可能会提供不足的内存来影响扩展,或者如果可以提供不足的内存来为新线程创建初始Java Virtual Machine堆栈,Java Virtual Machine会抛出一个OutOfMemoryError

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就会抛出一个OutOfMemoryError

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 OutOfMemoryError.
    如果方法区域中的内存不能满足分配请求,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).
运行时常量池是类文件中constant_pool表的每个类或每个接口的运行时表示(§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.
每个运行时常量池都是从Java虚拟机的方法区(§2.5.4)分配的类或接口的运行时常量池是在Java虚拟机(§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.
    在创建类或接口时,如果构建运行时常量池所需的内存超过Java Virtual Machine的方法区域所能提供的内存,则Java Virtual Machine将抛出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虚拟机的实现可以使用传统的栈,通俗地称为“C栈”,以支持本地方法(用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.
本地方法栈也可以被Java虚拟机指令集解释器的实现使用,例如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 StackOverflowError.
    如果线程中的计算需要比允许的更大的本地方法堆栈,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.
帧从创建帧的线程的Java虚拟机堆栈(§2.5.2)中分配。每一帧都有自己的局部变量数组(§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.
局部变量通过索引来处理。第一个局部变量的索引为零当且仅当整数小于局部变量数组的大小在0到1之间时,该整数被认为是局部变量数组的索引
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.
long类型或double类型的值占用两个连续的局部变量。这样的值只能使用较小的索引来处理。例如,存储在索引为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为偶数。直观地说,long和double类型的值不需要在局部变量数组中保持64位对齐。实现者可以使用为该值保留的两个局部变量自由决定表示这些值的适当方式。
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开始的连续局部变量中传递。在实例方法调用时,总是使用局部变量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)包含一个后进先出(LIFO)堆栈,即其操作数堆栈一个帧的操作数堆栈的最大深度是在【编译时】确定的,并与该帧相关的方法代码一起提供(§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虚拟机提供从本地变量或字段加载常量或值到操作数堆栈的指令。其他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.
操作数堆栈上的每个条目可以保存任何Java Virtual Machine类型的值,包括long类型或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虚拟机的一些实现中,类实例的引用是指向句柄的指针,句柄本身是一对指针:一个指向包含对象方法的表和代表对象类型的Class对象的指针,另一个指向从堆中分配给对象数据的内存

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虚拟机不支持IEEE 754信号浮点比较。

  • The rounding operations of the Java Virtual Machine always use IEEE 754 round to nearest mode. Inexact results are rounded to the nearest representable 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 convert values 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.
    Java虚拟机的舍入操作总是使用IEEE 754舍入到最近模式。不精确的结果会四舍五入到最接近的可表示值,而关联会到最低有效位为0的值。这是IEEE 754的默认模式。但是Java虚拟机指令将浮点类型的值转换为整数类型的值向零四舍五入。Java虚拟机没有提供任何方法来更改浮点舍入模式。

  • The Java Virtual Machine does not support either the IEEE 754 single extended or double extended format, except insofar as the double and double-extended-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 as extended exponent range.
    Java虚拟机既不支持IEEE 754单扩展格式也不支持双扩展格式,除非双扩展指数值集和双扩展指数值集可以被称为支持单扩展格式。可选支持的浮点扩展指数和双扩展指数值集与IEEE 754扩展格式的值不对应:IEEE 754扩展格式需要扩展的精度和扩展的指数范围。

2.8.2. Floating-Point Modes 浮点型模式

Every method has a floating-point mode, which is either FP-strict or not FP-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.
每个方法都有一个浮点模式,它要么是FP-strict,要么不是FP-strict。一个方法的浮点模式是由定义该方法的method_info结构(§4.6)的access_flags项的ACC_STRICT标志的设置决定的。设置此标志的方法是FP-strict;否则,该方法就不是严格的fp方法。
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 are effectively not FP-strict.
注意,ACC_STRICT标志的这种映射意味着在JDK 1.1版本或更早版本中由编译器编译的类中的方法实际上不是FP-strict。
We will refer to an operand stack as having a given floating-point mode when the method whose invocation created the frame containing the operand stack has that floating-point mode. Similarly, we will refer to a Java Virtual Machine instruction as having a given floating-point mode when the method containing that instruction has that floating-point mode.
当调用创建包含操作数堆栈的帧的方法具有浮点模式时,我们将操作数堆栈称为具有给定的浮点模式。类似地,当包含该指令的方法具有该浮点模式时,我们将Java虚拟机指令称为具有给定的浮点模式
If a float-extended-exponent value set is supported (§2.3.2), values of type float on an operand stack that is not FP-strict may range over that value set except where prohibited by value set conversion (§2.8.3). If a double-extended-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 except where prohibited by value set conversion.
如果支持浮点扩展指数值集(§2.3.2),则非fp严格的操作数堆栈上的float类型的值可以超过该值集,除非值集转换禁止(§2.8.3)。如果支持双扩展指数值集(§2.3.2),对于非fp严格的操作数堆栈,double类型的值可以超过该值集,除非值集转换禁止。
In all other contexts, whether on the operand stack or elsewhere, and regardless 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. In particular, class and instance fields, array elements, local variables, and method parameters may only contain values drawn from the standard value sets.
在所有其他上下文中,无论是在操作数堆栈上还是在其他地方,且不论浮点模式,float和double类型的浮点值只能分别在float值集和double值集上取值(扩展:JVM中的浮点数理论上是可以被穷举的Math.random()可以认为是等概率返回的伪随机数)。特别地,类和实例字段、数组元素、局部变量和方法参数可能只包含取自标准值集的值。

2.8.3. Value Set Conversion 值集转换

An implementation of the Java Virtual Machine that supports an extended floating-point value set is permitted or required, under specified circumstances, to map a value of the associated floating-point type between the extended and the standard value sets. Such a value set conversion is not a type conversion, but a mapping between the value sets associated with the same type.
在指定的情况下,支持扩展浮点值集的Java Virtual Machine实现允许或需要在扩展值集和标准值集之间映射一个相关浮点类型的值。这样的值集转换不是类型转换,而是与同一类型相关联的值集之间的映射
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.
    如果值是float类型且不是float值集的元素,则它将该值映射到float值集中最近的元素。
  • 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.
    如果值是double类型且不是双精度值集的元素,则它将该值映射到双精度值集中最近的元素。
    In addition, where value set conversion is indicated, certain operations are required:
    另外,在表示值集转换的地方,需要进行某些操作:
  • Suppose execution of a Java Virtual Machine instruction that is not FP-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, a field, or an element of an array. If the value is not an element of the float value set, it maps the value to the nearest element of the float value set.
    假设执行一个非fp严格的Java Virtual Machine指令会导致将float类型的值压入一个fp严格的操作数堆栈,作为参数传递,或存储到局部变量、字段或数组的元素中。如果该值不是浮点数集的元素,则它将该值映射到浮点数集中最近的元素
  • 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, a field, or an element of an array. If the value is not an element of the double value set, it maps the value to the nearest element of the double value set.
    假设执行一个非fp严格的Java Virtual Machine指令会导致double类型的值被压入一个fp严格的操作数堆栈,作为参数传递,或存储到局部变量、字段或数组的元素中。如果该值不是双精度值集的元素,则它将该值映射到双精度值集中最近的元素。
    Such required value set conversions may occur as a result of passing a parameter of a floating-point type during method invocation, including native method invocation; returning a value of a floating-point type from a method that is not FP-strict to a method that is FP-strict; or storing a value of a floating-point type into a local variable, a field, or an array in a method that is not FP-strict.
    在方法调用(包括本机方法调用)期间传递浮点类型参数时,可能会发生这种所需的值集转换;从非FP-strict方法返回浮点类型的值到FP-strict方法;或者将浮点类型的值存储到局部变量、字段或非fp严格方法中的数组中。
    Not all values from an extended-exponent value set can be mapped exactly to a value in the corresponding standard value set. If a value being mapped is too large to be represented exactly (its exponent is greater than that permitted by the standard value set), it is converted to a (positive or negative) infinity of 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 is rounded to the nearest of a representable denormalized value or zero of the same sign.
    并不是扩展指数值集中的所有值都能精确映射到相应的标准值集中的值。如果映射的值太大而无法精确表示(其指数大于标准值集允许的指数),则将其转换为对应类型的(正或负)无穷大如果一个被映射的值太小而不能精确地表示(它的指数小于标准值集允许的指数),那么它将四舍五入到最接近可表示的非规范化值或相同符号的零
    Value set conversion preserves infinities and NaNs and cannot change the sign of the value being converted. Value set conversion has no effect on a value that is not of a floating-point type.
    值集转换保留无穷大和NAN,不能更改正在转换的值的符号。值集转换对非浮点类型的值不起作用

2.9. Special Methods 特殊方法

At the level of the Java Virtual Machine, every constructor written in the Java programming language (JLS §8.8) appears as an instance initialization method that has the special name . This name is supplied by a compiler. Because the name is not a valid identifier, 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 the invokespecial instruction (§invokespecial), and they may be invoked only on uninitialized class instances. An instance initialization method takes on the access permissions (JLS §6.6) of the constructor from which it was derived.
在Java虚拟机的层次上,每个用Java编程语言(JLS§8.8)编写的构造函数都以实例初始化方法的形式出现,其特殊名称为。这个名称由编译器提供。因为名称不是一个有效的标识符,所以不能在用Java编程语言编写的程序中直接使用它。实例初始化方法只能在Java虚拟机内部通过invokspecial指令调用,并且只能在未初始化的类实例上调用。实例初始化方法具有派生它的构造函数的访问权限(JLS§6.6)。
在这里插入图片描述
A class or interface has at most one class or interface initialization method and is initialized (§5.5) by invoking that method. The initialization method of a class or interface has the special name , takes no arguments, and is void (§4.3.3).
一个类或接口最多有一个类或接口的初始化方法,并通过调用该方法进行初始化(§5.5)。类或接口的初始化方法有一个特殊的名称,不带参数,并且是void(§4.3.3)。
Other methods named in a class file are of no consequence. They are not class or interface initialization methods. They cannot be invoked by any Java Virtual Machine instruction and are never invoked by the Java Virtual Machine itself.
类文件中名为的其他方法没有任何结果。它们不是类或接口初始化方法。它们不能被任何Java虚拟机指令调用,并且永远不会被Java虚拟机本身调用。
In a class file whose version number 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.
在版本号为51.0或更高的类文件中,该方法必须另外设置ACC_STATIC标志(§4.6),以作为类或接口的初始化方法。
This requirement was introduced in Java SE 7. In a class file whose version number is 50.0 or below, a method named that is void and takes no arguments is considered the class or interface initialization method regardless of the setting of its ACC_STATIC flag.
Java SE 7中引入了这个需求。在版本号为50.0或更低的类文件中,名为且为void且不带参数的方法被视为类或接口初始化方法,无论其ACC_STATIC标志的设置如何。
The name is supplied by a compiler. Because the name is not a valid identifier, it cannot be used directly in a program written in the Java programming language. Class and interface initialization methods are invoked implicitly by the Java Virtual Machine; they are never invoked directly from any Java Virtual Machine instruction, but are invoked only indirectly as part of the class initialization process.
名称是由编译器提供的。因为名称不是一个有效的标识符,所以不能在用Java编程语言编写的程序中直接使用它。类和接口的初始化方法由Java虚拟机隐式调用;它们从不从任何Java虚拟机指令中直接调用,而是只作为类初始化过程的一部分间接调用。
A method is signature polymorphic if all of the following are true:
如果以下所有条件都为真,则该方法为签名多态方法:

  • It is declared in the java.lang.invoke.MethodHandle class.
    它在java.lang.invoke.MethodHandle类中声明。
  • It has a single formal parameter of type Object[].
    它只有一个Object[]类型的形参。
  • It has a return type of Object.
    它的返回类型是Object。
  • It has the ACC_VARARGS and ACC_NATIVE flags set.
    它设置了ACC_VARARGS和ACC_NATIVE标志。
    In Java SE 8, the only signature polymorphic methods are the invoke and invokeExact methods of the class java.lang.invoke.MethodHandle.
    在Java SE 8中,唯一的签名多态方法是类Java .lang.invoke. methodhandle的invoke和invokeExact方法

The Java Virtual Machine gives special treatment to signature polymorphic methods in the invokevirtual instruction (§invokevirtual), in order to effect invocation of a method handle. A method handle is a strongly typed, directly executable reference 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 are quite general, and include such patterns as conversion, insertion, deletion, and substitution. See the java.lang.invoke package in the Java SE platform API for more information.
Java虚拟机在invokvirtual指令(§invokvirtual)中对签名多态方法进行了特殊处理,以实现对方法句柄的调用。方法句柄是对底层方法、构造函数、字段或类似低级操作的强类型、可直接执行的引用(§5.4.3.5),具有可选的参数转换或返回值转换。这些转换非常普遍,包括转换、插入、删除和替换等模式。有关更多信息,请参阅Java SE平台API中的Java .lang.invoke包。
在这里插入图片描述

2.10. Exceptions 异常

An exception in the Java Virtual Machine is represented by an instance of the class Throwable or one of its subclasses. Throwing an exception results in an immediate nonlocal transfer of control from the point where the exception was thrown.
Java虚拟机中的异常由类Throwable或其子类之一的实例表示。抛出异常会导致从抛出异常的点立即转移控制。
Most exceptions occur synchronously as a result of an action by the thread in which they occur. An asynchronous exception, by contrast, can potentially occur at any point in the execution of a program. The Java Virtual Machine throws an exception for one of three reasons:
大多数异常都是由于发生异常的线程的操作而同步发生的。相比之下,异步异常可能发生在程序执行的任何时刻。Java虚拟机抛出异常的原因有以下三种:

  • An athrow instruction (§athrow) was executed.
    执行了一个throw指令(§athrow)。

  • An abnormal execution condition was synchronously detected by the Java Virtual Machine. These exceptions are not thrown at an arbitrary point in the program, but only synchronously after execution of an instruction that either:
    Java虚拟机同步检测到异常的执行情况。这些异常不会在程序中的任意点抛出,而只会在执行以下指令后同步抛出:

    Specifies the exception as a possible result, such as:
    指定异常作为可能的结果,例如:

    1. When the instruction embodies an operation that violates the semantics of the Java programming language, for example indexing outside the bounds of an array.
    当指令包含违反Java编程语言语义的操作时,例如在数组边界外进行索引。
    2. When an error occurs in loading or linking part of the program.
    在加载或链接程序的一部分时发生错误。
    

    Causes some limit on a resource to be exceeded, for example when too much memory is used.
    导致超出某个资源上的某些限制,例如当使用了太多内存时。

  • An asynchronous exception occurred because:
    发生异步异常的原因是:

    1. The stop method of class Thread or ThreadGroup was invoked, or
      调用类Thread或ThreadGroup的stop方法
    2. An internal error occurred in the Java Virtual Machine implementation.
      Java虚拟机实现出现内部错误。

The stop methods may be invoked by one thread to affect another thread or all the threads in a specified thread group. They are asynchronous because they may occur at any point in the execution of the other thread or threads. An internal error is considered asynchronous (§6.3).
一个线程可以调用stop方法来影响另一个线程或指定线程组中的所有线程。它们是异步的,因为它们可能发生在其他线程或线程执行的任何时刻。内部错误被认为是异步的(§6.3)。

A Java Virtual Machine may permit a small but bounded amount of execution to occur before an asynchronous exception is thrown. This delay is permitted to allow optimized code to detect and throw these exceptions at points where it is practical to handle them while obeying the semantics of the Java programming language.
在抛出异步异常之前,Java虚拟机可能允许少量但有限制的执行。这种延迟允许优化的代码检测并抛出这些异常,在符合Java编程语言语义的情况下处理它们是可行的。

A simple implementation might poll for asynchronous exceptions at the point of each control transfer instruction. Since a program has a finite size, this provides a bound on the total delay in detecting an asynchronous exception. Since no asynchronous exception will occur between control transfers, the code generator has some flexibility to reorder computation between control transfers for greater performance. The paper Polling Efficiently on Stock Hardware by Marc Feeley, Proc. 1993 Conference on Functional Programming and Computer Architecture, Copenhagen, Denmark, pp. 179–187, is recommended as further reading.
一个简单的实现可能会在每个控制传输指令点轮询异步异常。由于程序的大小是有限的,这就为检测异步异常的总延迟提供了一个界限。
由于在控制传输之间不会发生异步异常,代码生成器可以灵活地在控制传输之间重新排序计算,以获得更好的性能。Marc Feeley在Proc. 1993函数式编程和计算机架构会议上发表的《关于存储硬件的高效轮询》的论文,哥本哈根,丹麦,179-187页,推荐作为进一步阅读。

Exceptions thrown by the Java Virtual Machine are precise: when the transfer of control takes place, all effects of the instructions executed before the point from which the exception is thrown must appear to have taken place. No instructions that occur after the point from which the exception is thrown may appear to have been evaluated. If optimized code has speculatively executed some of the instructions which follow the point at which the exception occurs, such code must be prepared to hide this speculative execution from the user-visible state of the program.
Java虚拟机抛出的异常是精确的:当发生控制转移时,在抛出异常的点之前执行的指令的所有效果必须看起来像是已经发生了。在抛出异常的点之后发生的任何指令看起来都没有被求值。如果优化后的代码在异常发生点之后投机性地执行了一些指令,那么这些代码必须准备好对用户可见的程序状态隐藏这种投机性执行

Each method in the Java Virtual Machine may be associated with zero or more exception handlers. An exception handler specifies the range of offsets into the Java Virtual Machine code implementing the method for which the exception handler is active, describes the type of exception that the exception handler is able to handle, and specifies the location of the code that is to handle that exception. An exception matches an exception handler if the offset of the instruction that caused the exception is in the range of offsets of the exception handler and the exception type is the same class as or a subclass of the class of exception that the exception handler handles. When an exception is thrown, the Java Virtual Machine searches for a matching exception handler in the current method. If a matching exception handler is found, the system branches to the exception handling code specified by the matched handler.
Java虚拟机中的每个方法可以与零个或多个异常处理程序相关联。异常处理程序在实现异常处理程序活动的方法的Java虚拟机代码中指定偏移范围,描述异常处理程序能够处理的异常类型,并指定处理该异常的代码的位置。如果导致异常的指令的偏移量在异常处理程序的偏移量范围内,并且异常类型与异常处理程序处理的异常类或异常类的子类相同,则异常与异常处理程序匹配。当抛出异常时,Java虚拟机在当前方法中搜索匹配的异常处理程序。如果找到匹配的异常处理程序,系统将分支到匹配的处理程序指定的异常处理代码。

If no such exception handler is found in the current method, the current method invocation completes abruptly (§2.6.5). On abrupt completion, the operand stack and local variables of the current method invocation are discarded, and its frame is popped, reinstating the frame of the invoking method. The exception 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 before the top of the method invocation chain is reached, the execution of the thread in which the exception was thrown is terminated.
如果在当前方法中没有找到这样的异常处理程序,那么当前方法调用就会异常结束(§2.6.5)。在异常完成时,当前方法调用的操作数堆栈和局部变量被丢弃,它的框架被弹出,恢复调用方法的栈帧。然后在调用者的栈帧的上下文中重新抛出异常,以此类推,继续沿着方法调用链向上。如果在到达方法调用链的顶部之前没有找到合适的异常处理程序,则终止抛出异常的线程的执行

The order in which the exception handlers of a method are searched for a match is important. Within a class file, the exception handlers for each method are stored in a table (§4.7.3). At run time, when an exception is thrown, the Java Virtual Machine searches the exception handlers of the current method in the order that they appear in the corresponding exception handler table in the class file, starting from the beginning of that table.
方法的异常处理程序搜索匹配的顺序很重要。在类文件中,每个方法的异常处理都存储在一个表中(§4.7.3)。在运行时,当抛出异常时,Java Virtual Machine会按照当前方法在类文件中对应的异常处理程序表中出现的顺序,从表的开头开始搜索异常处理程序。

Note that the Java Virtual Machine does not enforce nesting of or any ordering of the exception table entries of a method. The exception handling semantics of the Java programming language are implemented only through cooperation with the compiler (§3.12). When class files are generated by some other means, the defined search procedure ensures that all Java Virtual Machine implementations will behave consistently.
注意,Java Virtual Machine并不强制方法的异常表项嵌套或排序。Java编程语言的异常处理语义只能通过与编译器的合作来实现(§3.12)。当通过其他方法生成类文件时,定义的搜索过程确保所有Java Virtual Machine实现的行为保持一致。

2.11. Instruction Set Summary 指令集的总结

A Java Virtual Machine instruction consists of a one-byte opcode specifying the operation to be performed, followed by zero or more operands supplying arguments or data that are used by the operation. Many instructions have no operands and consist only of an opcode.
Java Virtual Machine指令由一个字节的操作码组成,该操作码指定要执行的操作,后面跟着零个或多个操作数,提供操作所使用的参数或数据。许多指令没有操作数,只由操作码组成

Ignoring exceptions, the inner loop of a Java Virtual Machine interpreter is effectively
忽略异常,Java虚拟机解释器的内部循环是有效的

do {
    atomically calculate pc and fetch opcode 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 in big-endian order - high-order byte first. For example, an unsigned 16-bit index into the local variables is stored as two unsigned bytes, byte1 and byte2, such that its value is (byte1 << 8) | byte2.
操作数的数量和大小由操作码决定。如果一个操作数的大小超过一个字节,那么它将以大端顺序存储——首先是高阶字节。例如,本地变量的一个16位无符号索引存储为两个无符号字节byte1和byte2,这样它的值为(byte1 << 8) | byte2。

The bytecode instruction stream is only single-byte aligned. The two exceptions are the lookupswitch and tableswitch instructions (§lookupswitch, §tableswitch), which are padded to force internal alignment of some of their operands on 4-byte boundaries.
字节码指令流仅为单字节对齐。两个例外是lookupswitch和tableswitch指令(§lookupswitch,§tableswitch),它们被填充以强制它们的一些操作数在4字节边界上进行内部对齐

The decision to limit the Java Virtual Machine opcode to a byte and to forgo data alignment within compiled code reflects a conscious bias in favor of compactness, possibly at the cost of some performance in naive implementations. A one-byte opcode also limits the size of the instruction set. Not assuming data alignment means that immediate data larger than a byte must be constructed from bytes at run time on many machines.
将Java Virtual Machine操作码限制在一个字节内,并放弃编译代码中的数据对齐,这反映了一种有意识的倾向于紧凑,可能会以在原始实现中牺牲一些性能为代价一个字节的操作码也限制指令集的大小。不假设数据对齐意味着在许多机器上运行时必须使用字节构造大于一个字节的即时数据。

2.11.1. Types and the Java Virtual Machine 类型和Java虚拟机

Most of the instructions in the Java Virtual Machine instruction set encode type information about the operations they perform. For instance, the iload instruction (§iload) loads the contents of a local variable, which must be an int, onto the operand stack. The fload instruction (§fload) does the same with a float value. The two instructions may have identical implementations, but have distinct opcodes.
Java虚拟机指令集中的大多数指令对它们执行的操作的类型信息进行编码。例如,ilload指令(§ilload)将局部变量(必须是int型)的内容加载到操作数堆栈中加载指令(§fload)对浮点值执行相同的操作。这两条指令可能有相同的实现,但有不同的操作码。

For the majority of typed instructions, the instruction type is represented explicitly in the opcode mnemonic by a letter: i for 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 type letter in their mnemonic. For instance, arraylength always operates on an object that is an array. Some instructions, such as goto, an unconditional control transfer, do not operate on typed operands.
对于大多数类型化指令,**指令类型在操作码助记符中显式地用一个字母表示:i表示int操作,l表示long操作,s表示short操作,b表示byte操作,c表示char操作,f表示float操作,d表示double操作,a表示reference操作。**有些类型明确的指令在它们的助记符中没有一个类型字母。例如,arraylength总是作用于数组对象。有些指令(如goto,一种无条件的控制传输)不操作类型化的操作数。

Given the Java Virtual Machine’s one-byte opcode size, encoding types into opcodes places pressure on the design of its instruction set. If each typed instruction supported all of the Java Virtual Machine’s run-time data types, there would be more instructions than could be represented in a byte. Instead, the instruction set of the Java Virtual Machine provides a reduced level of type support for certain operations. In other words, the instruction set is intentionally not orthogonal. Separate instructions can be used to convert between unsupported and supported data types as necessary.
考虑到Java虚拟机的一个字节的操作码大小,将类型编码为操作码会给其指令集的设计带来压力。如果每个有类型的指令都支持Java虚拟机的所有运行时数据类型,那么指令数量将超过一个字节所能表示的数量。相反,Java虚拟机的指令集为某些操作提供了较低级别的类型支持。换句话说,指令集故意不是正交的。可以根据需要使用单独的指令在不支持的数据类型和支持的数据类型之间进行转换

Table 2.11.1-A summarizes the type support in the instruction set of the Java Virtual Machine. A specific instruction, with type information, is built by replacing the T in the instruction template in the opcode column by the letter in the type column. If the type column for some instruction template and type is blank, then no instruction exists supporting that type of operation. For instance, there is a load instruction for type int, iload, but there is no load instruction for type byte.
表2.11.1-A总结了Java虚拟机指令集对类型的支持。通过将指令模板中opcode列中的T替换为type列中的字母来构建一个特定的指令,该指令带有类型信息。如果某些指令模板的类型列和类型为空,则不存在支持该操作类型的指令。例如,有一个用于int类型的加载指令,ilload,但没有用于byte类型的加载指令。

Note that most instructions in Table 2.11.1-A do not have forms for the integral types byte, char, and short. None have forms for the boolean type. A compiler encodes 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 run-time. Loads of literal values of types boolean and char are encoded using instructions that zero-extend the literal to a value of type int at compile-time or run-time. 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, most operations on values of actual types boolean, byte, char, and short are correctly performed by instructions operating on values of computational type int.
请注意,表2.11.1-A中的大多数指令都没有byte、char和short整数类型的表单。没有用于boolean类型的表单编译器使用Java虚拟机指令对byte和short类型文字值的加载进行编码,该指令在编译时或运行时将这些值符号扩展为int类型的值。布尔型和char型文字值的加载使用指令进行编码,该指令在编译时或运行时将文字0扩展为int型值。同样,从布尔型、byte型、short型和char型值数组中加载的数据使用Java Virtual Machine指令进行编码,该指令将值符号扩展或0扩展为int型值。因此,对实际类型值布尔、byte、char和short的大多数操作都可以通过对值进行操作的指令正确地执行

Table 2.11.1-A. Type support in the Java Virtual Machine instruction set
在这里插入图片描述
The mapping between Java Virtual Machine actual types and Java Virtual Machine computational types is summarized by Table 2.11.1-B.
Java Virtual Machine实际类型与计算类型的对应关系如表2.11.1-B所示。
Certain Java Virtual Machine instructions such as pop and swap operate on the operand stack without regard to type; however, such instructions are constrained to use only on values of certain categories of computational types, also given in Table 2.11.1-B.
某些Java虚拟机指令,如pop和swap操作操作数栈而不考虑类型;然而,这样的指令只能用于特定类别的计算类型的值,如表2.11.1-B所示。
Table 2.11.1-B. Actual and Computational types in the Java Virtual Machine
表2.11.1-B。Java虚拟机中的实际类型和计算类型
在这里插入图片描述

2.11.2. Load and Store Instructions 加载和存储指令

The load and store instructions transfer values between the local variables (§2.6.1) and the operand stack (§2.6.2) of a Java Virtual Machine frame (§2.6):
加载和存储指令在Java虚拟机框架(§2.6)的本地变量(§2.6.1)和操作数堆栈(§2.6.2)之间传递值:

  • Load a local variable onto the operand stack: iload, iload_, lload, lload_, fload, fload_, dload, dload_, aload, aload_.
    将本地变量加载到操作数堆栈:

    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_, lstore, lstore_, fstore, fstore_, dstore, dstore_, astore, astore_.
    将操作数堆栈中的值存储到本地变量:

     istore, istore_<n>, lstore, lstore_<n>, fstore, fstore_<n>, dstore, dstore_<n>, astore, astore_<n>
    
  • Load a constant on to the operand stack: bipush, sipush, ldc, ldc_w, ldc2_w, aconst_null, iconst_m1, iconst_, lconst_, fconst_, dconst_.
    将一个常量加载到操作数堆栈:

     bipush, sipush, ldc, ldc_w, ldc2_w, aconst_null, iconst_m1, iconst_<i>, lconst_<l>, fconst_<f>, dconst_<d>
    
  • Gain access to more local variables using a wider index, or to a larger immediate operand: wide.
    使用更宽的索引访问更多局部变量,或访问更大的立即操作数:wide。

Instructions that access fields of objects and elements of arrays (§2.11.5) also transfer data to and from the operand stack.
访问对象字段和数组元素的指令(§2.11.5)也在操作数栈之间来回传输数据。

Instruction mnemonics shown above with trailing letters between angle brackets (for instance, iload_) denote families of instructions (with members iload_0, iload_1, iload_2, and iload_3 in the case of iload_). Such families of instructions are specializations of an additional generic instruction (iload) that takes one operand. For the specialized instructions, the operand is implicit and does not need to be stored or fetched. The semantics are otherwise the same (iload_0 means the same thing as iload with the operand 0). The letter between the angle brackets specifies the type of the implicit operand for that family of instructions: for , a nonnegative integer; for , an int; for , a long; for , a float; and for , 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).
上面的指令助记符后面的字母放在尖括号中(例如,iload_)表示指令族(iload_的情况下,成员为iload_0, iload_1, iload_2和iload_3)。
这种指令族是接受一个操作数的额外泛型指令(ilload)的专门化。对于专门化指令,操作数是隐式的,不需要存储或获取。语义在其他方面是相同的(iload_0意味着与操作数为0的ilload相同)。
尖括号之间的字母指定了该指令族隐式操作数的类型:对于,为非负整数;对于,为int;对于,长;对于,一个浮点数;对于,一个double。int类型的表单在很多情况下用于对byte、char和short类型的值进行操作(§2.11.1)。

This notation for instruction families is used throughout this specification.
此指令族表示法贯穿本规范。

2.11.3. Arithmetic Instructions 算术指令

The arithmetic instructions compute a result that is typically a function of two values on the operand stack, pushing the result back on the operand stack. There are two main kinds of arithmetic instructions: those operating on integer values and those operating on floating-point values. Within each of these kinds, the arithmetic instructions are specialized to Java Virtual Machine numeric types. There is 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 instructions also differ in their behavior on overflow and divide-by-zero. The arithmetic instructions are as follows:
算术指令计算的结果通常是操作数堆栈上两个值的函数,将结果推回操作数堆栈。主要有两种算术指令:整数值运算指令浮点值运算指令。在每一种类型中,算术指令都专门用于Java Virtual Machine数值类型。不支持对byte、short和char类型的值(§2.11.1)或布尔类型的值进行整数运算;这些操作由操作类型为int的指令处理。整数指令和浮点指令在溢出和被零除的行为上也有所不同。算法指令如下:

  • 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.
    取余
  • 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 by the semantics of the Java Virtual Machine instruction set.
Java编程语言对整数和浮点值操作符(JLS§4.2.2和JLS§4.2.4)的语义直接由Java虚拟机指令集的语义支持。

The Java Virtual Machine does not indicate overflow during operations on integer data types. The only integer operations that can throw an exception are the integer divide instructions (idiv and ldiv) and the integer remainder instructions (irem and lrem), which throw an ArithmeticException if the divisor is zero.
Java虚拟机不会在操作整数数据类型时提示溢出。唯一能引发异常的整数操作是整数除法指令(idiv和ldiv)和整数余数指令(irem和lrem),如果除数为零,它们会引发一个arithmeception异常

Java Virtual Machine operations on floating-point numbers behave as specified in IEEE 754. In particular, the Java Virtual Machine requires full support of IEEE 754 denormalized floating-point numbers and gradual underflow, which make it easier to prove desirable properties of particular numerical algorithms.
Java虚拟机对浮点数的操作与IEEE 754中规定的一样。特别是,Java虚拟机需要IEEE 754非规范化浮点数和渐进式下溢出的完全支持,这使得证明特定数值算法的理想特性变得更加容易。

The Java Virtual Machine requires that floating-point arithmetic behave as if every floating-point operator rounded its floating-point result to the result precision. Inexact results must be rounded to the representable value nearest 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 754 standard’s default rounding mode, known as round to nearest mode.
Java虚拟机要求浮点算术的行为好像每个浮点运算符都将其浮点结果舍入到结果精度。不精确的结果必须四舍五入到最接近无限精确结果的可表示值;如果两个最接近的可表示值相等,则选择具有最小有效位为零的那个。这是IEEE 754标准的默认舍入模式,即四舍五入模式

The Java Virtual Machine uses the IEEE 754 round towards zero mode when converting a floating-point value to an integer. This results in the number being truncated; any bits of the significand that represent the fractional part of the operand value are discarded. Round towards zero mode chooses as its result the type’s value closest to, but no greater in magnitude than, the infinitely precise result.
当将浮点值转换为整数时,Java虚拟机使用IEEE 754向零四舍五入模式。这导致数字被截断;表示操作数值的小数部分的有效位将被丢弃。四舍五入到零模式选择的结果是类型的值最接近,但在大小上不大于无限精确的结果。

The Java Virtual Machine’s floating-point operators do not throw run-time exceptions (not to be confused with IEEE 754 floating-point exceptions). An operation that overflows produces a signed infinity, an operation that underflows produces a denormalized value or a signed zero, and an operation that has no mathematically definite result produces NaN. All numeric operations with NaN as an operand produce NaN as a result.
Java虚拟机的浮点操作符不会抛出运行时异常(不要与IEEE 754浮点异常混淆)。溢出的操作产生有符号的无穷,下溢出的操作产生非规范化的值或有符号的零,没有数学上确定结果的操作产生NaN。所有使用NaN作为操作数的数值运算结果都是NaN。

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 IEEE 754 nonsignaling comparisons.
对long类型(lcmp)的值进行比较将执行带符号比较。使用IEEE 754非信令比较对浮点类型(dcmpg, dcmpl, fcmpg, fcmpl)的值进行比较。

2.11.4. Type Conversion Instructions 类型转换指令

The type conversion instructions allow conversion between Java Virtual Machine numeric types. These may be used to implement explicit conversions in user code or to mitigate the lack of orthogonality in the instruction set of the Java Virtual Machine.
类型转换指令允许在Java虚拟机数值类型之间进行转换。它们可以用于在用户代码中实现显式转换,或者缓解Java虚拟机指令集中缺乏正交性的问题。
The Java Virtual Machine directly supports the following widening numeric conversions:
Java虚拟机直接支持以下扩展的数字转换:

  • int to long, float, or double

  • long to float or double

  • float to double

The widening numeric conversion instructions are i2l, i2f, i2d, l2f, l2d, and f2d. The mnemonics for these opcodes are straightforward given the naming conventions for typed instructions and the punning use of 2 to mean “to.” For instance, the i2d instruction converts an int value to a double.
扩展的数值转换指令有i2l、i2f、i2d、l2f、l2d和f2d。这些操作码的助记符很简单,因为输入指令的命名约定和双关语用法2表示“to”。例如,i2d指令将int值转换为double值。
Most widening numeric conversions 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 numeric value exactly; only such conversions that are not FP-strict may lose information about the overall magnitude of the converted value.
大多数扩大的数值转换不会丢失关于数值整体大小的信息。实际上,从int扩展到long和从int扩展到double的转换完全不会丢失任何信息;数值被精确地保留。从float扩展到double的fp严格转换(§2.8.2)也会精确地保留数值;只有那些不是严格的fp转换可能会丢失关于转换值的总体大小的信息。
Conversions from int to float, or from long to float, or from long to double, may lose precision, that is, may lose some of the least significant bits of the value; the resulting floating-point value is a correctly rounded version of the integer value, using IEEE 754 round to nearest mode.
从int到float,或从long到float,或从long到double的转换可能会失去精度,也就是说,可能会失去值的一些最低有效位;得到的浮点值是整数值的正确四舍五入版本,使用IEEE 754四舍五入到最近模式。
Despite the fact that loss of precision may occur, widening numeric conversions never cause the Java Virtual Machine to throw a run-time exception (not to be confused with an IEEE 754 floating-point exception).
尽管可能会发生精度损失,但扩大的数值转换从未导致Java虚拟机抛出运行时异常(不要与IEEE 754浮点异常混淆)。
A widening numeric conversion of an int to a long simply sign-extends the two’s-complement representation of the int value to fill the wider format. A widening numeric conversion of a char to an integral type zero-extends the representation of the char value to fill the wider format.
从整型到长符号的扩展数值转换-扩展整型值的two’s-补表示以填充更宽的格式。char到整型类型0的扩展数值转换扩展了char值的表示,以填充更宽的格式。
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 these conversions implicit.
请注意,不存在从整数类型byte、char和short到int类型的扩展数值转换。如§2.11.1所述,byte、char和short类型的值在内部被扩展为int类型,使得这些转换是隐式的
The Java Virtual Machine also directly supports the following narrowing numeric conversions:
Java虚拟机还直接支持以下缩小数值转换:

  • 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 are i2b, i2c, i2s, l2i, f2i, f2l, d2i, d2l, and d2f. A narrowing numeric conversion can result in a value of different sign, a different order of magnitude, or both; it may thereby lose precision.
窄化数值转换指令为i2b、i2c、i2s、l2i、f2i、f2l、d2i、d2l和d2f。缩小数值转换可以产生不同符号的值、不同数量级的值,或两者兼有;因此,它可能会失去精度
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 same sign as the input value.
从整型或长型到整型T的缩小数值转换只会丢弃除n个最低阶位以外的所有位,其中n是用于表示类型T的位数。这可能会导致结果值与输入值不具有相同的符号。
In a narrowing numeric conversion of a floating-point value to an integral type T, where T is either int or long, the floating-point value is converted as follows:
在浮点值向整型T (T为int或long)的缩小数值转换中,浮点值的转换如下:

  • If the floating-point value is NaN, the result of the conversion is an int or long 0.如果浮点值为NaN,则转换的结果为int或长0。

  • Otherwise, if the floating-point value is not an infinity, the floating-point value is rounded to an integer value V using IEEE 754 round towards zero mode. There are two cases:
    否则,如果浮点值不是无穷大,则使用IEEE 754向零模式四舍五入将浮点值四舍五入为整数值V。有两种情况:

      If T is long and this integer value can be represented as a long, then the result is the long value V.
      如果T是长值,这个整数值可以表示为长值,那么结果就是长值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.
      如果T是整型,并且这个整型值可以表示为整型,那么结果就是整型值V。
    
  • Otherwise:
    否则:

      1. Either the value must be too small (a negative value of large magnitude or negative infinity), and the result is the smallest representable value of type int or long.
       该值必须太小(负值为大数值或负无穷大),结果是int或long类型的最小可表示值。
      
      2. Or the value must be too large (a positive value of large magnitude or positive infinity), and the result is the largest representable value of type int or long.
       或者值必须太大(大数量级的正值或正无穷大),结果是int或long类型的最大可表示值。
    

A narrowing numeric conversion from double to float behaves in accordance with IEEE 754. The result is correctly rounded using IEEE 754 round to nearest mode. A value too small to be represented as a float is converted to a positive 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 always converted to a float NaN.
从双精度浮点数到浮点数的缩小数值转换符合IEEE 754的要求。结果使用IEEE 754四舍五入到最接近的模式是正确的。太小而不能表示为float的值将转换为float类型的正零或负零;太大而不能表示为浮点数的值将转换为正无穷大或负无穷大。双NaN总是被转换为浮点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 run-time exception (not to be confused with an IEEE 754 floating-point exception).
尽管可能会发生溢出、下溢或精度损失,但缩小数值类型之间的转换绝不会导致Java Virtual Machine抛出运行时异常(不要与IEEE 754浮点异常混淆)。

2.11.5. Object Creation and Manipulation 对象创建和操作

Although both class instances and arrays are objects, the Java Virtual Machine creates and manipulates class instances and arrays using distinct sets of instructions:
虽然类实例和数组都是对象,但是Java虚拟机使用不同的指令集来创建和操作类实例和数组:

  • Create a new class instance: new.
    创建一个新的类实例:new。
  • Create a new array: newarray, anewarray, multianewarray.
    创建一个新数组: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): getstatic, putstatic, getfield, putfield.
    类的访问字段(静态字段,称为类变量)和类实例的字段(非静态字段,称为实例变量):getstatic, putstatic, getfield, putfield。
  • Load an array component onto the operand stack: baload, caload, saload, iaload, laload, faload, daload, aaload.
    将数组组件加载到操作数堆栈: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.
    从操作数堆栈中存储一个值作为数组组件:bastore, castore, sastore, iastore, lastore, fastore, dastore, aastore。
  • Get the length of array: arraylength.
    获取数组的长度:
  • Check properties of class instances or arrays: instanceof, checkcast.

2.11.6. Operand Stack Management Instructions 操作数堆栈管理指令

A number of instructions are provided for the direct manipulation of the operand stack: pop, pop2, dup, dup2, dup_x1, dup2_x1, dup_x2, dup2_x2, swap.

	为直接操作操作数堆栈提供了许多指令:pop, pop2, dup, dup2, dup_x1, dup2_x1, dup_x2, dup2_x2, swap。

2.11.7. Control Transfer Instructions 控制传输指令

The control transfer instructions conditionally or unconditionally cause the Java Virtual Machine to continue execution with an instruction other than the one following the control transfer instruction. They are:
控制传输指令有条件地或无条件地导致Java虚拟机继续执行除控制传输指令之后的其他指令。他们是:

  • Conditional branch: ifeq, ifne, iflt, ifle, ifgt, ifge, ifnull, ifnonnull, if_icmpeq, if_icmpne, if_icmplt, if_icmple, if_icmpgt if_icmpge, if_acmpeq, if_acmpne.

      条件分支:ifeq、ifne、iflt、ifle、ifgt、ifge、ifnull、ifnonnull、if_icmpeq、if_icmpne、if_icmpt、if_icmple、if_icmpgt、if_icmpge、if_acmpeq、if_acmpne。
    
  • Compound conditional branch: tableswitch, lookupswitch.

      复合条件分支:tableswitch, lookupswitch。
    
  • Unconditional branch: goto, goto_w, jsr, jsr_w, ret.

      无条件分支:goto, goto_w, jsr, jsr_w, ret。
    

The Java Virtual Machine has distinct sets of instructions that conditionally branch on comparison with data of int and reference types. It also has distinct conditional branch instructions that test for the null reference and thus it is not required to specify a concrete value for null (§2.4).
Java虚拟机有不同的指令集,它们有条件地根据int和引用类型数据的比较进行分支。它也有不同的条件分支指令来测试null引用,因此不需要为null指定一个具体的值(§2.4)。
Conditional branches on comparisons between data of types boolean, byte, char, and short are performed using int comparison instructions (§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 instruction tests this result and effects the conditional branch. Because of its emphasis on int comparisons, the Java Virtual Machine provides a rich complement of conditional branch instructions for type int.
boolean、byte、char和short类型数据比较的条件分支使用int比较指令执行(§2.11.1)。long、float或double类型的数据之间比较的条件分支是使用比较数据并产生比较的int结果的指令(§2.11.3)启动的。随后的int比较指令测试这个结果并影响条件转移。由于强调int类型比较,Java虚拟机为int类型提供了丰富的条件分支指令。
All int conditional control transfer instructions perform signed comparisons.
所有int条件控制传输指令都执行有符号比较

2.11.8. Method Invocation and Return Instructions 方法调用和返回指令

The following five instructions invoke methods:
以下5条指令调用方法:

  • invokevirtual invokes an instance method of an object, dispatching on the (virtual) type of the object. This is the normal method dispatch in the Java programming language.
    调用对象的实例方法,分派对象的(虚拟)类型。这是Java编程语言中常见的方法分派。
  • invokeinterface invokes an interface method, searching the methods implemented by the particular run-time object to find the appropriate method.
    调用接口方法,搜索由特定运行时对象实现的方法以找到适当的方法。
  • invokespecial invokes an instance method requiring special handling, whether an instance initialization method (§2.9), a private method, or a superclass method.
    调用需要特殊处理的实例方法,无论是实例初始化方法(§2.9)、私有方法还是超类方法。
  • invokestatic invokes a class (static) method in a named class.
    调用指定类中的类(静态)方法
  • invokedynamic invokes the method which is the target of the call site object bound to the invokedynamic instruction. The call site object was bound to a specific lexical occurrence of the invokedynamic instruction by the Java Virtual Machine as a result of running a bootstrap method before the first execution of the instruction. Therefore, each occurrence of an invokedynamic instruction has a unique linkage state, unlike the other instructions which invoke methods.
    调用方法,该方法是绑定到invokedynamic指令的调用站点对象的目标。调用站点对象被Java虚拟机绑定到invokedynamic指令的特定词法出现,这是在第一次执行指令之前运行引导方法的结果。因此,与调用方法的其他指令不同,invokedynamic指令的每次出现都有一个惟一的链接状态。
    The method return instructions, which are distinguished by return type, are ireturn (used to return values of type boolean, byte, char, short, or int), lreturn, freturn, dreturn, and areturn. In addition, the return instruction is used to return from methods declared to be void, instance initialization methods, and class or interface initialization methods.
    方法返回指令根据返回类型区分为ireturn(用于返回布尔型、byte型、char型、short型或int型的值)、lreturn、freturn、return和areturn。此外,返回指令用于从声明为void的方法、实例初始化方法以及类或接口初始化方法返回。

2.11.9. Throwing Exceptions 抛出异常

An exception is thrown programmatically using the athrow instruction. Exceptions can also be thrown by various Java Virtual Machine instructions if they detect an abnormal condition.
使用throw指令以编程方式抛出异常。如果各种Java Virtual Machine指令检测到异常情况,它们也可能引发异常。

2.11.10. Synchronization 同步

The Java Virtual Machine supports synchronization of both methods and sequences of instructions within a method by a single synchronization construct: the monitor.
Java Virtual Machine通过一个单一的同步构造(监视器)支持在一个方法中同步方法和指令序列。
Method-level synchronization is performed implicitly, as part of method invocation and return (§2.11.8). A synchronized method is distinguished in the run-time constant pool’s method_info structure (§4.6) by the ACC_SYNCHRONIZED flag, which is checked by the method invocation instructions. When invoking a method for which ACC_SYNCHRONIZED is set, the executing thread enters a monitor, invokes the method itself, and exits the monitor whether the method invocation completes normally or abruptly. During the time the executing thread owns the monitor, no other thread may enter it. If an exception is thrown during invocation of the synchronized method and the synchronized method does not handle the exception, the monitor for the method is automatically exited before the exception is rethrown out of the synchronized method.
方法级
同步是隐式执行的
,作为方法调用和返回的一部分(§2.11.8)。同步方法在运行时常量池的method_info结构(§4.6)中通过ACC_SYNCHRONIZED标志来区分,该标志由方法调用指令检查。当调用设置了ACC_SYNCHRONIZED的方法时,执行线程进入监视器,调用该方法本身,然后退出监视器,无论方法调用是正常完成还是异常完成。在执行线程拥有监视器的时间内,其他线程不能进入。如果在调用同步方法期间抛出异常,而同步方法不处理该异常,则在同步方法重新抛出异常之前自动退出该方法的监视器
Synchronization of sequences of instructions is typically used to encode the synchronized block of the Java programming language. The Java Virtual Machine supplies the monitorenter and monitorexit instructions to support such language constructs. Proper implementation of synchronized blocks requires cooperation from a compiler targeting the Java Virtual Machine (§3.14).
指令序列的同步通常用于对Java编程语言的同步块进行编码。Java虚拟机提供了monitorenter和monitoreexit指令来支持这种语言结构。同步块的正确实现需要Java虚拟机编译器的配合(§3.14)。
Structured locking is the situation when, during a method invocation, every exit on a given monitor matches a preceding entry on that monitor. Since there is no assurance that all code submitted to the Java Virtual Machine will perform structured locking, implementations of the Java Virtual Machine are permitted but not required to enforce both of the following two rules guaranteeing structured locking. Let T be a thread and M be a monitor. Then:
结构化锁定是这样一种情况:在方法调用期间,给定监视器上的每个出口都与该监视器上的前一个条目匹配。由于不能保证提交给Java Virtual Machine的所有代码都将执行结构化锁定,所以Java Virtual Machine的实现允许但不是必须执行以下两条保证结构化锁定的规则。设T为线程,M为监视器。然后:
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.
在方法调用期间,T对M执行的监视器条目数量必须等于方法调用期间T对M执行的监视器出口数量,无论方法调用是正常完成还是异常完成。

  1. At no point during a method invocation may the number of monitor exits performed by T on M since the method invocation exceed the number of monitor entries performed by T on M since the method invocation.
    在方法调用期间,T在M上执行的监控器出口的数量不能超过自方法调用以来T在M上执行的监控器条目的数量。
  2. Note that the monitor entry and exit automatically performed by the Java Virtual Machine when invoking a synchronized method are considered to occur during the calling method’s invocation.
    注意,Java Virtual Machine在调用同步方法时自动执行的监视器入口和出口被认为是在调用方法的过程中发生的。

2.12. Class Libraries 类库

The Java Virtual Machine must provide sufficient support for the implementation of the class libraries of the Java SE platform. Some of the classes in these libraries cannot be implemented without the cooperation of the Java Virtual Machine.
Java虚拟机必须为Java SE平台的类库的实现提供足够的支持。如果没有Java虚拟机的合作,这些库中的一些类就无法实现。
Classes that might require special support from the Java Virtual Machine include those that support:
可能需要Java虚拟机特殊支持的类包括:

  • Reflection, such as the classes in the package java.lang.reflect and the class Class.
    反射,例如java.lang.reflect包中的类和类class。
  • Loading and creation of a class or interface. The most obvious example is the class ClassLoader.
    加载和创建类或接口。最明显的例子是ClassLoader类。
  • Linking and initialization of a class or interface. The example classes cited above fall into this category as well.
    链接和初始化类或接口。上面引用的示例类也属于这一类。
  • Security, such as the classes in the package java.security and other classes such as SecurityManager.
    安全,如java包中的类。security和其他类(如SecurityManager)。
  • Multithreading, such as the class Thread.
    多线程,比如Thread类。
  • Weak references, such as the classes in the package java.lang.ref.
    弱引用,例如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 is beyond the scope of this specification. See the specifications of the Java SE platform class libraries for details.
    面的列表是用来说明问题的,而不是全面的。这些类或它们提供的功能的详尽列表超出了本规范的范围。详细信息请参见Java SE平台类库的规范。

2.13. Public Design, Private Implementation 公共设计,私有实现

Thus far this specification has sketched the public view of the Java Virtual Machine: the class file format and the instruction set. These components are vital to the hardware-, operating system-, and implementation-independence of the Java Virtual Machine. The implementor may prefer to think of them as a means to securely communicate fragments of programs between hosts each implementing the Java SE platform, rather than as a blueprint to be followed exactly.
到目前为止,该规范概述了Java虚拟机的公共视图:类文件格式和指令集。这些组件对于Java虚拟机的硬件独立性、操作系统独立性和实现独立性至关重要。实现者可能更愿意将它们看作是在每个实现Java SE平台的主机之间安全地通信程序片段的一种方法,而不是要严格遵循的蓝图。
It is important to understand where the line between the public design and the private implementation lies. A Java Virtual Machine implementation must be able to read class files and must exactly implement the semantics of the Java Virtual Machine code therein. One way of doing this is to take this document as a specification and to implement that specification literally. But it is also perfectly feasible 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 may implement these semantics in any way. What is “under the hood” is the implementor’s business, as long as the correct external interface is carefully maintained.
重要的是要理解公共设计和私有实现之间的界限在哪里。Java虚拟机实现必须能够读取类文件,并且必须准确地实现其中的Java虚拟机代码的语义。一种方法是将该文档作为规范,并按字面意思实现该规范。但是,对于实现者来说,在本规范的约束下修改或优化实现也是完全可行和理想的。只要可以读取类文件格式,并维护其代码的语义,实现者就可以以任何方式实现这些语义。只要仔细维护正确的外部接口,“底层”是实现者的业务。
There are some exceptions: debuggers, profilers, and just-in-time code generators can each require access to elements of the Java Virtual Machine that are normally considered to be “under the hood.” Where appropriate, Oracle works with other Java Virtual Machine implementors and with tool vendors to develop common interfaces to the Java Virtual Machine for use by such tools, and to promote those interfaces across the industry.
有一些例外:调试器、分析器和即时代码生成器都需要访问Java Virtual Machine的元素,这些元素通常被认为是“在底层的”。在适当的情况下,Oracle与其他Java虚拟机实现者和工具供应商合作,为这些工具开发Java虚拟机的通用接口,并在整个行业推广这些接口。

The implementor can use this flexibility to tailor Java Virtual Machine implementations for high performance, low memory use, or portability. What makes sense in a given implementation depends on the goals of that implementation. The range of implementation options includes the following:
实现者可以使用这种灵活性来定制Java Virtual Machine实现,以实现高性能、低内存使用或可移植性。在一个给定的实现中什么是有意义的取决于该实现的目标。实施方案的范围包括:

  • Translating Java Virtual Machine code at load-time or during execution into the instruction set of another virtual machine.
    在加载时或执行时将Java虚拟机代码转换为另一个虚拟机的指令集。
  • Translating Java Virtual Machine code at load-time or during execution into the native instruction set of the host CPU (sometimes referred to as just-in-time, or JIT, code generation).
    在加载时或执行时将Java虚拟机代码转换为主机CPU的本机指令集(有时称为即时代码生成或JIT代码生成)。
    The existence of a precisely defined virtual machine and object file format need not significantly restrict the creativity of the implementor. The Java Virtual Machine is designed to support many different implementations, providing new and interesting solutions while retaining compatibility between implementations.
    精确定义的虚拟机和目标文件格式的存在不需要显著地限制实现者的创造力。Java虚拟机被设计成支持许多不同的实现,提供新的和有趣的解决方案,同时保持实现之间的兼容性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值