[JVM] 5. 运行时数据区(2)-- 程序计数器(Program Counter Register)

ゞ 浴缸里的玫瑰 2024-03-17 21:08 126阅读 0赞

一、概述

  1. JVM中的程序计数器(Program Counter Register)是对物理PC寄存器的一种抽象模拟。
  2. 它是一块很小的内存空间,几乎可以忽略不记。也是运行速度最快的存储区域。
  3. 在 JVM 规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致。
  4. 任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的 Java 方法的 JVM 指令地址;或者,如果是在执行 native 方法(本地方法),则是未指定值(undefined)。
  5. 它是唯一一个在Java虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域,因为它存储的是一个可预见大小的值。

092004b870464f4ab6b101de8ca2681c.png

二、作用

程序寄存器(Program Counter Register)用来存储 下一条指令的地址,由执行引擎来读取下一条指令并执行。

字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令

例如这段代码:

3be94117670c4932b829e6f7542f15cb.png

我们对这段代码进行编译,的到PCRegisterTest.class,然后执行javap命令进行反编译。

a7cc2515032e4c9ea714ca769039a248.png

我们查看这段代码:

9007d5550bbc471091aa9a844e29551e.png

左边一列0、2、3等是指令的偏移地址,右边的bipush 10等就是指令。

简单理解地址为0、地址为2的两个指令的意义是:把10压栈到1的位置。

整体理解如下图:

c29e3abc14a041ae891be20884ff9515.png

提前理解一下栈帧,一个栈帧可以理解为一个方法。

image-20220423212939649

三、常见问题

1. 使用PC寄存器存储字节码指令地址有什么用呢? 或者是 为什么使用 PC 寄存器来记录当前线程的执行地址呢?

因为CPU需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行。JVM的字节码解释器就需要通过改变PC寄存器的值来明确下一条应该执行什么样的字节码指令。

2. PC寄存器为什么被设定为线程私有?

  • 我们都知道所谓的多线程在一个特定的时间段内只会执行其中某一个线程的方法,CPU会不停地做任务切换,这样必然导致经常中断或恢复,如何保证分毫无差呢?为了能够准确地记录各个线程正在执行的当前字节码指令地址,最好的办法自然是为每一个线程都分配一个PC寄存器,这样一来各个线程之间便可以进行独立计算,从而不会出现相互干扰的情况。
  • 由于CPU时间片轮限制,众多线程在并发执行过程中,任何一个确定的时刻,一个处理器或者多核处理器中的一个内核,只会执行某个线程中的一条指令。
  • 这样必然导致经常中断或恢复,如何保证分毫无差呢?每个线程在创建后,都会产生自己的程序计数器和栈帧,程序计数器在各个线程之间互不影响。
  • 在创建后,都会产生自己的程序计数器和栈帧,程序计数器在各个线程之间互不影响。

参考:

3. 运行时数据区及程序计数器 · 语雀

百度安全验证

JVM运行时数据区_仅此而已_的博客-CSDN博客

JVM程序计数器_android jvm 程序计数器_轩*的博客-CSDN博客

JVM-第4章-程序计数器(Program Counter Register)_program priority register_小成同学_的博客-CSDN博客

为什么JVM规范中,程序计数器不会发生OutOfMemoryError_纵有疾风起 人生不言弃的博客-CSDN博客

发表评论

表情:
评论列表 (有 0 条评论,126人围观)

还没有评论,来说两句吧...

相关阅读

    相关 运行数据——程序计数器

    概念  程序计数器是一块较小的内存空间,他可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),