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虚拟机定义了在程序执行期间使用的各种运行时数据区域。
2.5.1. The pc Register pc寄存器
The Java Virtual Machine can support many threads of execution at once (JLS §17). Each Java Virtual Machine thread has its own
pc
(program counter) register. At any point, each Java Virtual Machine thread is executing the code of a single method, namely the current method ( §2.6
) for that thread. If that method is not
native
, the
pc
register contains the address of the Java Virtual Machine instruction currently being executed. If the method currently being executed by the thread is
native
, the value of the Java Virtual Machine's
pc
register is undefined. The Java Virtual Machine's
pc
register is wide enough to hold a
returnAddress
or a native pointer on the specific platform.
Java虚拟机支持一次执行多个线程。每个Java虚拟机线程都有自己的pc(程序计数器)寄存器。在任何时刻,每个Java虚拟机线程都在执行单个方法的代码,即该线程的当前方法。如果该方法不是本地方法,则pc寄存器包含当前正在执行的Java虚拟机指令的地址。如果线程当前执行的方法是本地的,则Java虚拟机的pc寄存器的值是未定义的。Java虚拟机的pc寄存器足够宽,可以容纳特定平台上的返回地址或本地指针。
程序计数器补充
每个线程都有一个程序计数器。程序计数器是线程私有的,相当于一个指针,是一个很小的内存空间,是指方法区中的方法字节码由引擎读取下一条指令。
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). A Java Virtual Machine stack is analogous to the stack of a conventional language such as C: it holds local variables and partial results, and plays a part in method invocation and return. Because the Java Virtual Machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java Virtual Machine stack does not need to be contiguous.
Java虚拟机线程都有一个与线程同时创建的私有的Java虚拟机堆栈。Java虚拟机堆栈存储帧(
栈帧)。Java虚拟机堆栈类似于传统语言(如C语言)的堆栈:它保存局部变量和部分结果,并在方法调用和返回中起作用。因为除了push帧和pop帧之外,Java虚拟机堆栈从未被直接操作,所以帧可能被分配为堆。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虚拟机堆栈具有固定的大小,或者根据计算的需要动态扩展和收缩。如果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虚拟机堆栈超出允许的最大值,Java虚拟机将抛出一个堆栈溢出错误。
- 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虚拟机栈可以动态地扩展,会出现情况
栈-补充
栈又被称为栈内存,负责Java程序的运行,线程创建时创建,线程消亡时被释放。因此,栈的生命周期与线程的生命周期一致。
栈不存在垃圾回收的问题,线程结束时就释放栈。
类变量、引用类型变量、实例方法等都是在函数的栈内存分配好的。
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. 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.
堆是在虚拟机启动时创建的。堆存储的对象由自动存储管理系统(称为垃圾收集器)回收;对象永远不会被显式释放。Java虚拟机假设自动存储管理系统没有特殊类型,可以根据实现者的系统需求选择存储管理技术。堆的大小可以是固定的,也可以根据计算的需要进行扩展,如果不需要更大的堆,则可以收缩。堆的内存不需要是连续的。
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虚拟机实现可以为程序员或用户提供对堆初始大小的控制,如果堆可以动态扩展或收缩,还可以控制堆的最大和最小大小。
The following exceptional condition is associated with the heap:
下列异常情况与堆相关:
如果计算需要的堆比自动存储管理系统所能提供的堆多,Java虚拟机就会抛出OutOfMemoryError。
堆-补充
- 存储对象实例,例如new创建的对象都在堆分配。
- 堆中对象内存需要GC回收,是JVM共享区。
2.5.4. Method Area 方法区
The Java Virtual Machine has a method area that is shared among all Java Virtual Machine threads. 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 used in class and interface initialization and in instance initialization (§2.9).
Java虚拟机有一个在所有Java虚拟机线程之间共享的方法区域。方法区域类似于常规语言的已编译代码的存储区域,或类似于操作系统进程中的“文本”段。它存储每个类的结构,例如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括在类和接口初始化以及实例初始化中使用的特殊方法(§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。
方法区补充
方法区是所有线程共享使用的区域,通常用来保存装载类的元结构信息。方法区也是GC的作用区域。
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). 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.
运行时常量池是类文件(§4.4)中constant_pool表的每个类或每个接口的运行时表示。它包含几种类型的常量,从编译时已知的数值常量到必须在运行时解析的方法和字段引用。运行时常量池的功能类似于传统编程语言的符号表,尽管它包含的数据范围比典型的符号表更广。
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虚拟机的方法区域所能提供的内存,则Java虚拟机将抛出OutOfMemoryError。
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). 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编程语言以外的语言编写的方法)。本地方法栈的使用可以通过解释器实现,解释器会解释翻译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。
补充:
Heap, Mehtod Area是被所有线程共享使用,由GC回收内存。Stack, pc Register, Native Method Stack是以线程为粒度,每个线程都各自的部分,与所在的线程生命周期一致。
GC 垃圾回收
- GC作用区:方法区和堆。
- GC通过确定对象引用来判断是否收集该对象。
- GC通常使用方法:引用计数法和对象引用便利。
参考链接: https://docs.oracle.com/javase/specs/index.html