运行时数据区
JVM定义了运行时数据区,这是一个JVM逻辑上组织管理内存的模型,并不代表物理存储结构。线程共享堆和方法区,线程私有各自的虚拟机栈,本地方法栈,程序计数器。
堆
- 对象实例:几乎所有的对象实例都在堆上分配。包括通过关键字
new
创建的对象以及通过一些反射方法、字符串常量池中的字符串对象等。 - 数组:无论是对象数组还是基本数据类型的数组,都在堆上分配。
- 类实例变量:对象的成员变量(不包括定义为
static
的静态成员变量),无论它们是基本数据类型还是对象引用,都存储在堆中的对象实例中。 - 字符串常量池:字符串常量池中存储着所有的字符串字面量和字符串对象。字符串字面量是直接在代码里以双引号包围的字符串值。
方法区
包含已被虚拟机加载的类信息、运行时常量池、静态变量。
- 类信息:被ClassLoader加载后的类元信息。
- 运行时常量池:除了字符串字面量特别存储在字符串常量池之外,其他类型的字面量以及符号引用都存储在运行时常量池中。
- 静态变量:类级别的变量,不属于类的任何单个实例。
HotSpot JVM 1.8中,方法区由元空间实现,并存放在本地内存而不是JVM虚拟机内存。
虚拟机栈
每当一个方法被调用时,JVM会为这次调用创建一个新的栈帧并压入虚拟机栈中。
- 局部变量表:存储方法的参数和方法内部定义的局部变量。
- 操作数栈:存放计算过程中的中间结果,以及作为执行字节码操作的工作区。
- 动态链接:每个栈帧内部包含指向运行时常量池的引用,用于支持方法调用过程中的动态链接,例如解析方法调用、字段访问等。
- 方法返回地址:当方法调用完成后,控制权需要返回到方法被调用的位置,栈帧中存储了这个返回地址。
本地方法栈
用于管理本地方法(非Java方法)的调用。本地方法由C语言实现。
Hotspot JVM中把虚拟机栈和本地方法栈合一。
程序计数器
存储当前线程指向下一条指令的地址