一、运行时数据区的简单概述
继上篇学习的类加载系统,现在来看一下jvm其中的另一部分——运行时数据区,这里可以简单的理解为内存,程序运行时,类的实例对象、需要的数据都保存在这里,执行引擎根据jvm指令操作栈帧也在这里执行。当然。Jvm也对运行时数据区做了一些划分,如下图所示:
我们可以看到,运行时数据区主要分为五个部分:
1、本地方法栈
2、程序计数器(PC寄存器)
3、虚拟机栈
4、堆区
5、元数据区(方法区)
其中,堆和元数据区是线程共享的,生命周期是随着jvm的启动而创建,也随着jvm的退出而销毁;而本地方法栈、虚拟机栈和程序计数器则是线程独立的,也就是每一个线程都有各自的本地方法栈、虚拟机栈和程序计数器,当然他们的生命周期也随着线程的开始和结束,进行相对应的创建和销毁。
二、程序计数器
- 是什么
Jvm运行时数据区的一部分,叫Program Count Register,也有人叫PC寄存器。
- 做什么工作
程序计数器用来存储指向下一条指令的地址,也就是即将要执行的指令代码。执行引擎会在这里读取地址,找到对应的指令,然后执行指令。
我们可以编写一个简单的程序,编译成class后,用javap -v进行反编译一下,看一下反编译后的字节码文件。
程序:
反编译后:
大致的工作原理:
- 有什么作用
1、它是程序执行的指示器,分支、循环、异常、跳转等基础的功能都依赖它实现;
2、字节码解释器工作时,就是通过改变它的值来选取下一条指令;
3、它是唯一一个在Java虚拟机规范中没有规定OOM情况的区域。
- 它为什么是线程不共享的?为什么要存当前线程的指令地址?
在多线程的情况下,cpu工作时会不停的切换任务,这当切出当前线程的时候,pc寄存器把执行到哪里的指令地址存下来,当切回当前线程的时候,jvm才知道从哪里继续开始执行指令。所以每个线程创立的时候,jvm都会分配给他们对应的程序计数器和栈,不同线程的程序计数器不受彼此影响。