前言:本文是讲解关于JVM内存区域介绍的文章,主要参考了《Java虚拟机规范Java SE 8版》。
Rapid自动内存管理可以说是jvm特性中最优秀的特性之一,Java程序员不用关心内存泄漏和内存溢出问题,还可以更加专注的关系业务功能开发,能够提高JAVA程序员的生产效率,不像C++程序员需要对每个对象由始到终的生命负责。
这种特性虽然带来了很多的好处,但是一旦出现内存泄漏或者内存溢出的问题,如果不了解JAVA虚拟机是如何分配使用内存的,那么排查问题将会变成非常困难。
为了让我们可以解开JAVA虚拟机的内存管理的神秘面纱,本篇文章将会从概念上介绍JAVA虚拟机的各个区域,分别讲解各个区域的用处,以及可能产生的问题。
参考链接:docs.oracle.com/javase/8/do…
JVM运行时数据区到底包含哪些部分呢?
运行时数据区逻辑图示例
下面我们一个一个区域来了解。
一、程序计数器(The pc Register)
The Java Virtual Machine can support many threads of execution at once (JLS §17). Each 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.
大致意思是每个线程都有自己的程序计数器,对于非本地方法而言,它是用来记录当前线程正在执行的jvm指令地址,对于本地方法而言,计数器记录的是undefined。jvm程序计数器在不同平台都有足够大的空间来存储一个返回地址或者一个本地指针,因为这个区域是唯一一个不会存在OutOfMemoryError情况的区域。
二、(Java虚拟机栈)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 First Edition of The Java® Virtual Machine Specification, 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.
大致意思是Java虚拟机栈也是线程私有的,它的生命周期随着线程创建而开始,随着线程结束而终止。java虚拟机栈存储的是局部变量表和局部结果,在方法执行和返回过程中扮演着重要角色。java虚拟机栈的内存不需要是连续的。这块内存区域的大小支持固定或者动态扩展。
Java虚拟机栈有可能出线内存溢出问题,如果线程请求的栈深度大于虚拟机允许的栈深度,则会抛出StackOverflowError问题,如果虚拟机栈支持动态扩展,当虚拟机栈动态扩展过程中无法申请到足够的内存,就会抛出OutOfMemoryError问题。
三、堆(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
意思是说堆是线程共享的一块内存区域,java中所有类实列和数组实例都是存储在该区域
这个区域被java垃圾收集器自动管理分配回收,且是隐式的进行管理,该区域内存支持固定大小或者动态扩展(通过-Xmx和-Xms控制)
如果需要的内存比可分配的内存大则会抛出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 maybe 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
意思是方法区是线程共享的区域,用于存储虚拟机加载的类信息,常量,静态变量,方法和构造函数的代码,它逻辑上属于堆内存,该区域的内存不要求是连续的
当方法区无法满足内存分配需求时,将抛出OutOfMemoryError问题。
五、运行时常量池(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 runtime 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
意思是运行时常量池属于方法区的一部分,他是类文件中常量池的表现形式,用来存储编译期生成的字面量或者符号引用,还有运行期生成的直接引用
该区域受到方法区内存大小的限制,当常量池无法再申请到足够内存时会抛出OutOfMemoryError问题。
六、本地方法栈(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.
意思是JVM会实现一个C栈来支持不是用java语言的方法,或者用来实现JVM的指令集的翻译器
同Java虚拟机栈一样,本地方法栈也可能出现StackOverflowError或者OutOfMemoryError问题