JVM运行期内存结构(Run-Time Data Areas)

这里翻译自:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html 第2.5节运行期数据区域划分.

JVM规范定义了程序在运行期间不同数据区域的划分。其中部分数据是在JVM启动时创建,同时在JVM结束时消失。另一些则与线程相关,在线程被创建时被创建,线程结束时这部分数据被删除。
总共的区域划分为 PC寄存器线程执行栈数据堆方法区常量池本地执行栈,共6个区域。

A PC寄存器

在同一时刻,在JVM内部有多个线程在同时执行。在某一时刻,线程就会取出一条指令进行执行,那么PC寄存器就表示当前线程正在执行哪一条指令,即正在执行指令的一个引用指针,以方便进行定位和执行下一条指令。即寄存器会同时记录每个线程的执行点。如果当前线程正在执行native方法时,寄存器的值是未定义的。

B 线程执行栈

线程执行栈即表示每一个线程在执行不同的方法所创建的按方法区分的帧。就比如在调用ex.printStackTrace时,每一个调用方法就表示一个方法帧。在每个方法帧上,存储着在当前执行点上存储的一些临时变量以及下个方法返回的数据值。在具体执行时,当调用一个新方法时,就会创建一个新的执行帧,同时push到当前的执行栈中;当方法返回时,就会把当前的执行帧从执行栈中pop掉。

在具体实现时,每个执行栈的内存并没有要求一定是连续的。
在某些情况下,特别是在递归调用中,经常会报StackOverflowError的错误,就是因为创建的执行帧太多,而每个执行帧会占用一定的内存。当总执行栈超过设定值时,就会发生这个异常。比如,在Oracle JVM上,可以通过-Xss来指定每个执行栈的最大内存。

C 数据堆

JVM数据堆即我们通常所说的保存所有数据,如对象,变量的区域,它是所有线程共享的。所有的数据内存均从这些进行分配。

在具体编码时,我们并不需要显示的进行分配内存,也不需要显示的释放掉相应的内存。这一切均由JVM实现自行处理,在具体实现时,并不要求数据的存储是按照特定的顺序存储,也不要求存储空间一定是连续的。只需要在JVM启动之前,配置相应的内存大小值,由JVM实现自行管理内存的增长和压缩。同时,内存中数据的释放由JVM的GC实现来进行处理,具体如何实现,也由JVM实现自行处理。
如在Oracle JVM中,我们可以通过Xms和Xmx来设定堆的最小值和最大值。

D 方法区

方法区即存放在运行过程中所有的语法结构数据的区域,这些结构信息包括运行常量池,类信息,字段信息,方法信息,构造方法以及一些特定的类初始方法和数据初始方法等。

与运行常量池不一样的,这里存储的数据均可以理解为是已经结构化的,包括相应的数据关系也已建立。如我们在调用class.getDeclaredFields时,数据信息便会从方法区中获取。

方法区同样也是存储在数据堆中的,但并没有要求这个区域也会进行GC,具体的实现可以不回收这部分区域。比如在Oracle JVM中(1.7及以下),可以通过MaxPermSize配置这部分内存大小。如在现在我们经常使用ASM及javassist等自动产生类的框架中,经常产生PermGenException,即因为动态产生的类的信息会存储在方法区中,不断的产生,就会导致这部分内存占用增长,即表示方法区的内存量太小,不能够存放过多的信息。

E 常量池

简单来讲,运行常量池就是在class文件中定义的constant_pool。具体的存储数据包括,类,字段,方法的描述信息(主要为字符串结构),以及int,float,long,double,string这些常量信息,也称之为符号表。在运行过程中,某些常量信息会被解析以作为特定的执行引用(如类,方法定义等)。其中这里需要注意即是这个string,在明文定义在class中的字符串均存放在常量池中。这些定义可以说构成了我们常说的字符串池的大部分内容。

对于JVM来说,常量池是全局共享的,即不同文件中定义的同一个字符串常量会引用同样的内存地址。
运行常量池并不是在JVM启动时便保存所有信息,而是当一个新的class被解析时,相应文件(表示这个类)中的constant_pool信息才会被解析存储至常量池中。
常量池在存储中是存储在方法区中的,表示方法区的一部分。

F 本地方法栈

本地方法栈即表示native方法在执行时所属的区域,这部分并不由原来的线程执行栈来控制和管理。这部分的实现由JVM实现自行处理,也不要求一定要与线程执行栈的结构一样。

以上信息并没有针对一些细节性的限制进行处理,只是从程序的角度进行简单的描述。如一些exception的处理和条件限制也未细述,这些均与JVM实现相关,因此这里简单略过。以下是原文。

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.

A: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. 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.

B:Java Virtual Machine Stacks

Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread. A Java Virtual Machine stack stores frames (§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.

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

This specification permits Java Virtual Machine stacks either to be of a fixed size or to dynamically expand and contract as required by the computation. If the Java Virtual Machine stacks are of a fixed size, the size of each Java Virtual Machine stack may be chosen independently when that stack is created.

A Java Virtual Machine implementation may provide the programmer or the user control over the initial size of Java Virtual Machine stacks, as well as, in the case of dynamically expanding or contracting Java Virtual Machine stacks, control over the maximum and minimum sizes.

The following exceptional conditions are associated with Java Virtual Machine stacks:

  • If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws a StackOverflowError.
  • If Java Virtual Machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java Virtual Machine stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError.

C: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.

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.

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.

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.

D: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 (§2.9) used in class and instance initialization and interface initialization.

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 version of the Java Virtual Machine 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.

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.

E: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.

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.

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.

F: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.

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.

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.
  • 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.

转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/201402170001.html

相关文章:

作者: flym

I am flym,the master of the site:)

发表评论

电子邮件地址不会被公开。 必填项已用*标注