运行时数据区之pc寄存器

我正在参加「掘金·启航计划」

官方描述:

image.png 翻译过来就是: Java 虚拟机可以同时支持多个执行线程(JLS §17)。每个 Java 虚拟机线程都有自己的 pc(程序计数器)寄存器。在任何时候,每个 Java 虚拟机线程都在执行单个方法的代码,即该线程的当前方法(第 2.6 节)。如果该方法不是 native,则pc寄存器包含当前正在执行的 Java 虚拟机指令的地址。如果线程当前正在执行的方法是native,则 Java 虚拟机的pc 寄存器的值是未定义的。Java 虚拟机的pcregister 的宽度足以容纳returnAddress特定平台上的本地指针或本地指针。

验证

直接上代码,新建一个PcRegisterTest类创建一个main方法,如下图:

image.png 运行运行main方法生成class文件,在target目录下找到对应的class文件通过javap -v PcRegisterTest.calss查看当前类的信息其中就包括字节码指令如下图:

image.png

上图红框框起来的就是字节码指令,pc寄存器就是存储这些执行的字节码指令地址的,并且记录当前线程执行到哪一步指令,为什么指令不共享,原因就是在多线程情况下如果共享字节码指令,假设线程一执行到的代码行数是10,此时线程二拿到了执行权由第十行执行到20,线程三完成剩下的全部逻辑执行完成,那么显然对于现线程一、二是未执行完的本来应该三个线程都执行一次逻辑变成了三个线程只执行了一次逻辑,虽然执行的是同一段代码逻辑,但是结果确不一样。

所以对于线程来说,pc寄存器、虚拟机栈、本地方法栈都是唯一的,是线程级别的,这样一来各个线程之间便可以进行独立计算,从而不会出现相互干扰的情况。 image.png

pc寄存器的结论

(参考官网:docs.oracle.com/javase/spec…

  1. JVM中的程序计数寄存器(Program Counter Register)中,Register的命名源于CPU的寄存器,寄存器存储指令相关的现场信息。CPU只有把数据装载到寄存器才能够运行。
  2. 这里,并非是广义上所指的物理寄存器,或许将其翻译为PC计数器(或指令计数器)会更加贴切(也称为程序钩子),并且也不容易引起一些不必要的误会。JVM中的PC寄存器是对物理PC寄存器的一种抽象模拟
  3. 它是一块很小的内存空间,几乎可以忽略不记。也是运行速度最快的存储区域。
  4. 在JVM规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致。
  5. 任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址;或者,如果是在执行native方法,则是未指定值(undefned)。
  6. 它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
  7. 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。
  8. 它是唯一一个在Java虚拟机规范中没有规定任何OutofMemoryError情况的区域。

猜你喜欢

转载自juejin.im/post/7154604110526808071