JVM内存模型:
java虚拟机的内存空间分为五个部分,分别是:
1.程序计数器
2.java虚拟机栈
3.本地方法栈
4.堆
5.方法区
一、程序计数器:
是一块较小的内存空间,可以把它看成当前线程正在执行的字节码的行号指示器,也就是说,程序计数器里边记录了当前线程正在执行的那一条字节码指令的地址。
如果当前线程执行的是一个本地方法,那么程序计数器为空。
程序计数器的作用:
1.字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,例如 顺序、选择、循环、异常。
2.在多线程情况下,程序计数器用于记录当前线程的执行位置,从而使得当线程被切换回来时能够知道上次运行到哪。
程序计数器的特点:
是一块较小的内存区域
线程私有,每个线程都有一个程序计数器。
是唯一一个不会出现outOfMemory的内存区域。
生命周期随着线程的创建而产生,随着线程的消亡而消失。
二、java虚拟机栈:
java虚拟机栈是用来描述java方法运行过程的内存模型。
java虚拟机栈会为每个即将执行的java方法创建一块叫栈帧的区域,这块区域用于存储该方法在运行过程中所需要的一些信息。
这些信息主要包括:
(1)局部变量表:存放基本数据类型、引用类型的变量、returnAddress类型的变量
(2)操作数栈
(3)动态链接
(4)方法出口信息
当一个方法即将被运行时,java虚拟机栈会为该方法在虚拟机栈中创建一块“栈帧”,栈帧中包含局部变量表、操作数栈、动态链接、方法出口信息等。
当方法在运行过程中需要创建局部变量时,就将局部变量的值存入局部变量表中。当这个方法执行完毕时,这个方法所对应的栈帧将会出栈,并释放内存空间。
注意:人们常说,Java的内存空间分为“栈”和“堆”,栈中存放局部变量,堆中存放对象。
这句话不完全正确!这里的“堆”可以这么理解,但这里的“栈”只代表了Java虚拟机栈中的局部变量表部分。
真正的Java虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。
虚拟机栈的特点:
局部变量表的创建是在方法被执行的时候,随着栈帧的创建而创建。而且,局部变量表的大小在编译时期就确定下来了,
在创建的时候只需分配事先规定好的大小即可。此外,在方法运行的过程中局部变量表的大小是不会发生改变的。
Java虚拟机栈会出现两种异常:StackOverFlowError和OutOfMemoryError。
a) StackOverFlowError: 若Java虚拟机栈的内存大小不允许动态扩展,
那么当线程请求栈的深度超过当前Java虚拟机栈的最大深度的时候,就抛出StackOverFlowError异常。
b) OutOfMemoryError: 若Java虚拟机栈的内存大小允许动态扩展,且当线程请求栈时内存用完了,无法再动态扩展了,
此时抛出OutOfMemoryError异常。Java虚拟机栈也是线程私有的,每个线程都有各自的Java虚拟机栈,
而且随着线程的创建而创建,随着线程的死亡而死亡。注:StackOverFlowError和OutOfMemoryError的异同?
StackOverFlowError表示当前线程申请的栈超过了事先定好的栈的最大深度,但内存空间可能还有很多。
而OutOfMemoryError是指当线程申请栈时发现栈已经满了,而且内存也全都用光了。
JVM 内存模型 (一)
最新推荐文章于 2024-06-22 22:32:15 发布