本文部分参考自《Java虚拟机规范(Java SE 7版)》的中译本和周志明的《深刻理解Java虚拟机》,另加我的理解。原书对Java虚拟机运行时数据区描述只有6页,同时参考其余网络网资料,我的能力所限,不排除存在认知错误。 数组
JVM将程序运行期间使用的内存划分为若干个运行时数据区,其中一些会随着虚拟机启动而建立,随着虚拟机退出而销毁。另一些与线程一一对应,随着线程开始而建立,随着线程结束而销毁。数据区划分以下图所示意: 网络
Java堆(Java Heap) 数据结构
在JVM中,Java堆是可供各个线程共享的运行时内存区域,是供全部类实例和数组对象分配内存的区域。Java堆在虚拟机启动时被建立,存储了垃圾收集器(GC)管理的各类对象,这些对象没法显式销毁。 函数
Java堆可能发生OutOfMemoryError错误。 spa
方法区(Method Area) 线程
方法区用于存储已被虚拟机加载的类的结构信息,例如:运行时常量池、字段和方法数据、构造函数和普通方法的字节码,还包括一些在类、实例、接口初始化时用到的特殊方法。 对象
方法区逻辑上是Java堆的一部分,但JVM规范对方法区限制很是宽松,能够选择不实现垃圾收集。实际由于类型卸载的条件很是苛刻,方法区的垃圾收集效果也不理想。 接口
方法区可能发生OutOfMemoryError错误。 内存
运行时常量池(Runtime Constant Pool) 虚拟机
每一个类或接口的字节码中去了有类的版本、字段、方法、接口等描述信息外,还包含一个常量池表(constant_pool table),用于存放编译期生成的各类字面值和符号引用,运行时常量池是这个常量池表的运行时表示形式。每一个运行时常量池都在JVM的方法区中分配,在加载类和接口到虚拟机后,就建立对应的运行时常量池。
在建立运行时常量池时,JVM可能会抛出OutOfMemoryError错误。
PC计数器(Program Counter Register)
JVM线程私有,保存当前线程正在执行的字节码指令的地址,若是正在执行的是Native方法,值为undefined,本内存区域没有规定内存错误。
Java虚拟机栈(Java Virtual Machine Stack)
在初版中也称为Java Stack,每一条JVM线程都有本身私有的Java虚拟机栈,这个栈与线程同时建立,用于存储栈帧(Frame)。
Java虚拟机栈可能发生StackOverFlowError和OutOfMemoryError错误。
本地方法栈(Native Method Stack)
JVM线程私有,和Java虚拟机栈做用相似,Java虚拟机栈为虚拟机执行Java方法服务,而本地方法栈为虚拟机执行Native方法服务。JVM规范没有规定本区域如何实现,Sun HotSpot虚拟机直接把本地方法栈和Java虚拟机栈合成了一个。和Java虚拟机栈同样,本地方法栈也可能抛出StackOverFlowError和OutOfMemoryError错误。
栈帧(Stack Frame)
栈帧是用于存储数据和部分过程结果的数据结构,每次方法调用对应一个栈帧,随着方法调用而建立,随着方法结束而销毁。栈帧的空间分配在Java虚拟机栈中,每一个栈帧包括本身的本地变量表、操做数栈和动态连接(指向当前方法所属类的运行时常量池的引用)。