-
JVM体系结构
-
运行时内存区
class 字节码文件通过类装载器加载,在运行时的数据区包括方法区 (Method Area) 、虚拟机栈 (VM Stack) 、本地方法栈 (Native Method Stack) 、堆 (Heap) 、程序计数器 (Program Couter Register)。-
方法区 (Method Area) :主要用于存储类的结构信息、运行常量池(runtime constant pool)、静态变量、方法代码、方法数据等。是所有线程共享的。方法区逻辑上属于堆的一部分,但又与堆进行区分,通常又叫“非堆”。
- 运行常量池(runtime constant pool):是class 文件中每一个类或接口的常量池表(constant_pool table)的运行时表示形式,包括若干种不同的常量,从编译期可知的数值字面量到必须在运行期解析后才能获得的方法或字段引用。每一个运行时常量池在Java 虚拟机的方法区中分配。
-
Java 虚拟机栈 (JAVA Virtual Machine Stack) :是描述 Java 方法执行的内存模型。每个线程有一个私有的栈,随着线程创建而建立,主要用于存放一种叫“栈帧”的东西。每个方法被执行时会创建一个“栈帧”,用于存储局部变量表(基本数据类型和对象引用)、操作数栈、方法出口等信息。每个方法被调用到执行完的过程,就对应着一个栈帧在虚拟机中从入栈到出栈的过程。栈的大小可以固定也可以动态扩展。当栈调用深度大于JVM所允许的范围,会抛出*Error异常,不过,这个深度范围不是一个恒定的值。另外,当申请不到空间时,会抛出OutOfMemorryError 异常。
- 栈帧(frame):是用来存储数据和部分过程结果的数据结构,同时也用来处理动态链接(dymanic linking),方法返回值,异常分派(dispatch excepiton)。栈帧是随着方法的调用而创建,随着方法结束而销毁。栈帧是线程本地私有的数据,没可能在一个栈帧只用引用另一个线程的栈帧。
本地方法栈 (Native Method Stack) :Java 虚拟机实现可能会用使用到传统的栈(C Stack)支持native 方法。当 Java 虚拟机使用到其他语言(例如 C 语言)来实现指令集解释器时,也可以使用本地方法栈,与虚拟机栈基本类似,区别在于虚拟机栈为虚拟机执行的Java 方法服务,而本地方法则是为Native方法服务。
堆 (Heap) :也叫Java 堆,是可供各个线程共享的运行时内存区域。在虚拟机启动的时候就被创建,存储了被自动内存管理系统garbage collector(垃圾收集器),是Java虚拟机所管理的内存中最大的一块内存区域。提供类实例和数组对象分配内存的区域。 Java 堆的容量可以是固定的,也可以随着程序执行的需求动态扩展,并不需要过多空间时自动收缩。如果实际所需的堆超过了自动内存管理系统提供的最大容量,会抛出一个OutOfMemorryError异常
- 程序计数器 (Program Couter Register) :也叫PC寄存器,,每一条 Java 虚拟机线程都有自己的 PC寄存器,在任意时刻,一条虚拟机线程只会执行一个方法代码,这个正在被线程执行的方法成为线程的当前方法。作用是当前线程所执行的字节码的行号指示器,在虚拟机的模型里,字节码解释器的工作就是通过该表这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、异常处理、线程恢复等基础功能都是依赖计数器完成的。
-
方法区 (Method Area) :主要用于存储类的结构信息、运行常量池(runtime constant pool)、静态变量、方法代码、方法数据等。是所有线程共享的。方法区逻辑上属于堆的一部分,但又与堆进行区分,通常又叫“非堆”。