一、程序计数器
1.概念:
程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。
2.作用:
字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制。如:顺序执行、选择、循环、异常处理。
在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪。
3.生命周期:
随着线程的创建而创建,随着线程的结束而死亡。
4.异常:
程序计数器是唯一一个不会出现OutOfMemoryError的内存区域。
二、虚拟机栈
1.概念:
描述的是Java方法执行的内存模型。
2.作用:
由一个个栈帧组成,每个栈帧用来存储出局部变量表、操作数栈、动态链接、方法出口。
局部变量表中存储八大原始类型、对象引用和return Address
3.生命周期:
随线程的创建而创建,随线程的死亡而死亡。
4.异常:
Java虚拟机栈会出现两种异常:StackOverFlowError和OutOfMemoryError
(1)StackOverFlowError:
若Java虚拟机栈的内存大小不允许动态扩展,当线程请求栈的深度超过当前Java虚拟机栈的最大深度时,就抛出。
(2)OutOfMemoryError:
若Java虚拟机栈的内存大小允许动态扩展,且当线程请求栈时内存用完了,无法再动态扩展。
三、本地方法栈
和虚拟机栈发挥作用相似。
1.和虚拟机栈区别:
虚拟机栈为虚拟机执行Java方法(字节码服务),本地方法栈则为虚拟机用到的Native方法服务。
2.作用:
被执行时也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息,方法执行完毕后相应的栈帧也会出栈并释放内存空间。
3.异常:
也会出现StackOverFlowError和OutOfMemoryError两种异常
四、堆
1.概念:
Java堆时所有线程共享的一块内存区域,在虚拟机启动时创建。(内存最大)
2.作用:
存放对象实例(几乎所有对象实例和数组都在这分配内存)。Java堆时垃圾收集器管理的主要区域,因此也被称作GC堆。
3.空间划分:
永久代说明:
jdk1.6及之前:常量池分配在永久代。
jdk1.7:有永久代,但已逐步“去永久代”。
jdk1.8:移除整个永久代,取而代之的是一个叫元空间的区域。
五、方法区
1.作用:
存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
2.异常:
当方法区无法满足内存分配需求时,抛出OutOfMemoryError。