程序计数器:用来储存指向下一条指令的地址,也就是即将要执行的指令代码,由执行引擎来读取下一条指令.
程序计数器是一块很小的内存空间,但也是运行速度最快的存储区域
JVM规范中,每一个线程中都有属于自己的程序计数器,它是线程私有的,其生命周期和线程的生命周期保持一致
任何时候,一个线程中都只有一个方法在执行,即当前方法,程序计数器会存储当前线程正在执行的Java方法的JVM指令地址,如果执行native方法(本地方法),则是未指定值.
注意以下几点:
1.它是程序控制流的指示器,分支,跳转,异常处理,线程恢复等基础功能都需要依赖程序计数器来完成.
2.字节码解释器工作时就是通过程序计数器来选取下一条需要执行的字节码指令.
3.它是唯一一个在Java虚拟机规范中没有规定任何OOM(OutOfMemoryError),即内存溢出情况的区域
常见面试问题
1.为什么使用程序计数器来记录当前线程的执行地址?
解析:cpu需要不断进行各个线程之间的切换操作,当从一个线程从到另一个线程切换回来的时候,需要知道接下来从哪里开始继续执行,就是接下来执行指令的地址位置,而JVM的字节码解释器就需要通过不断地改变PC计数器的值来明确下一条应该执行什么样的字节码指令了.
2.PC计数器为什么要设置为线程私有的?
第一种回答:多线程在一个特定的时间段只会执行其中的某一个线程的方法,cpu会不停的进行任务的切换,这样必然会导致经常发生线程的中断和恢复工作,那么让其可以做到没有丝毫问题,就需要在每一个线程中设置自己的pc计数器,来记录各个线程自己正在执行的当前字节码指令地址,这样一来各个线程之间可以进行独立的计算,从而不会出现相互干扰的情况.
第二种回答:由于cpu时间片轮限制(时间片即是cpu分配给各个程序的时间,每个线程被分配的一个时间段,称作为它的时间片),而当众多线程在并发执行过程中,任何一个确定的时刻,一个处理器或者多核处理器的一个内核,只会执行某一个线程中一条指令,这样会导致经常性的中断或者恢复,如何可以保证其分毫不差,则可以在每个线程创建以后,都会创建自己的程序计数器和栈帧,其程序计数器在各个线程中是相对独立,互不影响的.