Java内存区域与内存溢出异常

96
夏洛克大王
2018.01.02 17:40* 字数 1781

Java虚拟机,以下简称JVM。

JVM在执行java程序的过程中会把它所管理的内存划分为若干个区域。

这些区域有各自的生命周期。有的依赖于JVM,有的依赖于用户线程。

6块区域组成。

程序计数器 The pc Register

JVM可以同时支持许多执行线程。每个JVM线程有自己的程序计数器。任何时候,每个JVM线程执行单个方法的代码,叫做那个线程的当前方法。如果那个方法不是本地的,那么程序计数器包含当前JVM正在执行的指令地址。如果被这个线程当前执行的方法是本地的,那么JVM的程序计数器的值是undefined。JVM的程序计数器足够去持有一个返回地址或者一个本地指针在指定的平台。翻译自JVM规范。

简单来说

JVM执行非本地方法,它的程序计数器存指令地址。

JVM执行本地方法,它的程序计数器存值undefined。

tag:线程隔离的数据区

Java虚拟机栈 Java Virtual Machine Stacks

每个JVM线程有一个私有JVM栈,与线程一起被创建。一个JVM栈存frames。一个JVM栈是类似于传统语言C的栈:它有本地变量和局部变量,在方法调用和返回中起着作用。因为JVM栈从不直接被操作除了放和取frames,frames按照堆放置。对于JVM栈内存不需要用到。

第一版java虚拟机规范中,JVM栈叫Java栈。

这个规范允许JVM栈是固定大小或者是动态扩展以及根据计算的得到。

如果JVM栈大小是固定的,每个JVM栈被独立的选择当栈被创建时。

每个JVM实现可以提供程序或者用户控制基于JVM栈的初始大小,同样的动态扩展的或者contractingJVM栈,控制在最大和最小大小。

下面是JVM栈的异常条件

如果计算后线程要求一个更大的JVM栈比起所允许的,JVM抛出StackOverflowError.

如果JVM栈是动态扩展的,当扩展中没有足够的内存或者没有足够的内存去初始化JVM栈的一个线程,JVM抛出OutOfMemoryError

简单来说

JVM中每个线程有一个JVM栈,与线程一起被创建。每个JVM栈用来存frames。

frame is used to store data and partial results, as well as to perform dynamic linking, return values for methods, and dispatch exceptions.

 Local Variables

Operand Stacks

 Dynamic Linking

Normal Method Invocation Completion

Abrupt Method Invocation Completion

frames

java 堆 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.

方法区 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 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.

运行时常量池 Run-Time Constant Pool


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.

See §5 (Loading, Linking, and Initializing) for information about the construction of the run-time constant pool.

本地方法栈 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 nativemethods 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.


参考

深入理解Java虚拟机 周志明 著

JVM规范链接

Web note ad 1