JVM运行时数据区


简介


运行时数据区(Runtime Data Area)是保存JVM线程示例执行过程中数据的区域;

包括要加载的类文件信息、线程执行过程中的暂存数据、线程执行的位置、

运行时数据区中分为以下个区域
- 虚拟机栈(VM stack)
- 本地方法栈(native method stack)
- 程序计数器(program counter register)
- 堆(heap)
- 方法区(method area)


虚拟机栈


虚拟机栈是虚拟机线城实例的执行区域,保存着虚拟机线程的执行状态(类似于上下文的概念);
虚拟机栈中的存储单位为栈帧,每个栈帧保存着当前虚拟机线程执行的某个方法的信息,线程执行过程中对方法的调用和调用完成对应的操作也即为栈帧的压栈和出栈;

remark

严格意义上来讲,虚拟机栈并不能完全支撑“保存着虚拟机线程执行状态”这一说法;
除了创建的对象和数组需要放在堆中,虚拟机栈仅保留对象和数组的引用之外;
而线程执行相关的状态,例如处理器在切换线程时需要保存线程当前执行的节点等信息则不再虚拟机栈中保存,而是在“程序计数器中”;
这么看来,栈保存的信息更多的偏向内容信息的概念;


存储

stack中存放两种类型数据
- java的八种基本数据类型;
- 对象的引用;

线程中的体现

虚拟机栈为虚拟机线程私有的区域,每个虚拟机栈维护着对应线程的执行状态,互相不能访问;

生命周期

由上可见,虚拟机栈的生命周期即为虚拟机线程的生命周期;

异常情况

当线程请求虚拟机栈的深度大于虚拟机栈允许的最大深度时,抛出StackOverFlowError;
如果当前虚拟机支持虚拟机栈的可扩展,则可能出现另一种异常:当虚拟机栈扩展时如果无法申请足够的内存空间,会抛出OutOfMemoryError;

另外
我们通常讲的“JVM栈”就是当前的虚拟机栈,因为实际在运行时数据区中,还存在另一个栈-本地方法栈。


本地方法栈


本地方法栈和虚拟机栈上类似,“保存着虚拟机线程的执行状态”,唯独不同的是,两个栈的的使用场景不同:虚拟机栈是为虚拟机线程执行java方法时保存状态信息;而本地方法栈顾名思义是保存虚拟机线程执行native方法时的状态信息。


存储
线程中的体现

虚拟机栈为虚拟机线程私有的区域,每个虚拟机栈维护着对应线程的执行状态,互相不能访问;(同虚拟机栈)

生命周期

由上可见,虚拟机栈的生命周期即为虚拟机线程的生命周期;(同虚拟机栈)

异常情况

同虚拟机栈一样,存在这StackOverFlowError和OutOfMemoryError两种异常;

remark

>


程序计数器


又称“PC寄存器”?whatever~

程序计数器的开头由处理器多线程的处理方式来说起最合适不过;在处理器中,一个处理器核(CPU core)某一个时间点只能处理一个线程,线程之间的并发是通过分时切换,间断性的轮流切换执行多个线程;
例如单核处理器中的两个线程A和B,可能执行线程A一段时间后虽然当前线程A并未结束,处理器可以将线程A挂起,转而去执行线程B,并且也可以在不执行完线程B的时候重新继续执行线程A;

管理处理器在多线程情况下的处理这里就简单点缀一下;

总之,虚拟机线程需要保存当前线程执行节点状态,以实现上述的线程切换的情况;


存储

当执行java方法时,存储当前线程
当执行native方法时,程序计数器内容为空(undifined);

线程中的体现

综上所述,可见程序计数器和“虚拟机栈”和“本地方法栈”一样属于线程私有的区域,相 互独立并且不能互相访问;

生命周期

同上,程序计数器的生命周期也跟虚拟机线程保持一致;

异常情况

程序计数器是在Java虚拟机规范中唯一不存在任何OutOfMemoryError异常的区域;


运行时数据区中堆的唯一目的就是存放对象实例,在虚拟机创建时创建堆(分配内存),且几乎所有虚拟机对堆的实现都是可扩展的;
堆是虚拟机垃圾回收器管理的主要区域;


存储
  • 对象(包括数组)
线程中的体现

堆为虚拟机中所有线程所共享;

生命周期

堆的生命周期跟虚拟机生命周期保持一致;

异常情况

当堆在进行扩展时如果无法获取足够的内存空间会跑出OutOfMemoryError异常;


方法区

虽然一般命名为方法区,但其实保存的不仅仅是方法,用类型信息来描述更合适;所存储的类型信息由类加载器子系统从class文件中提取之后放入;
为堆中创建对象时准备所需的材料;


存储

-保存类的类型信息;具体如下:
类的全限定名
当前类的直接父类的全限定名
这个类是接口类型, 类类型, 还是枚举类型
类的访问修饰符信息
当前类型的超接口的全限定名
当前类型的常量池
字段信息
方法信息

remark

个人更倾向于将方法区分为:
类的相关信息;
类的ClassLoader对象的引用;
类的Class实例对象的引用;
运行时常量池;

线程中的体现

综上所述,可见程序计数器和“虚拟机栈”和“本地方法栈”一样属于线程私有的区域,相 互独立并且不能互相访问;

生命周期

同上,程序计数器的生命周期也跟虚拟机线程保持一致;

异常情况

当堆在进行扩展时如果无法获取足够的内存空间会跑出OutOfMemoryError异常;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值