运行时数据区
包括:程序计数器(PC寄存器)、Java虚拟机栈、Java堆、方法区、运行时常量池、本地方法栈等等。
程序计数器
程序计数器也叫做PC寄存器
- JVM支持多个线程同时运行,每个线程拥有一个程序计数器,是线程私有的,用来存储指向下一条指令的地址。
- 在创建线程的时候,创建相应的程序计数器。
- 执行本地native方法时,程序计数器的值为undefined。
- 是一块比较小的内存空间,是唯一一个在JVM规范中没有规定OutOfMemoryError的内存区域。
虚拟机栈
- 栈是由一系列帧(Frame)组成(因此Java栈也叫作帧栈),是线程私有的。
- 帧是用来保存一个方法的局部变量、操作数栈(java没有寄存器,所有的参数传递使用操作数栈)、常量池指针、动态链接、方法返回值等。
- 每一次方法调用创建一个帧并压栈,退出方法的时候,修改栈顶指针就可以把栈帧中的内容销毁。
栈的优点:存取速度比堆快,仅次于程序计数器。
栈的缺点:存在栈中的数据太小,生存期是在编译期决定的,缺乏灵活性。
StackOverflowError异常:当线程请求的栈深度大于虚拟机所允许的深度;
OutOfMemoryError异常:如果栈的扩展时无法申请到足够的内存。
本地方法栈
在JVM中用来支持native方法执行的栈
堆
用来存放应用系统创建的对象和数组,所有线程共享堆。是内存最大的一块区域,也是GC主要区域
方法区
方法区是所有线程共享的,用来保存装载的类的结构信息。
理解
运行时数据区
,也就是下图这部分,它是在类加载类加载完成后的阶段
当通过前面的:类的加载 --> 验证 --> 准备 --> 解析 --> 初始化,这几个阶段完成后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会使用到运行时数据区
比如大厨做饭,我们把大厨后面的东西(
切好的菜,刀,调料
),比作是运行时数据区
。而厨师
可以类比于执行引擎
,将通过准备的东西制作成精美的菜品
总结
- 线程私有结构:程序计数器、虚拟机栈、本地方法栈
- 每个虚拟机栈由具体的栈帧组成,在栈帧的动态链接中,保存至对方法的引用
- 方法区在 JDK7 之前,使用永久代实现,在 JDK8 之后,使用元空间实现
- Minor GC 针对于新生区,Major GC 针对于老年区,Full GC 针对于整个堆空间和方法区