程序计数寄存器

程序计数寄存器

什么是程序计数寄存器?

  • 名称:程序计数寄存器(Programmer Counter Register)

    • 别名:PC 寄存器、程序计数器、程序钩子
  • 定义:JVM 中的一块较小的 [内存区域]{.blue}

    • 区别:真实计算机中的程序计数器是 [物理硬件寄存器]{.blue} 制作完成的
  • 作用:[保存当前线程正在执行的字节码指令的地址]{.red}

    • 字节码指令:源代码被编译器编译后生成的就是字节码文件(包含字节码指令)
    • 字节码指令地址:每个字节码指令都具有自己的地址,便于执行引擎选择执行
    • 编译器:C/C++ 的编译器是 GCC,Java 的编译器是的 Javac
    字节码指令
  • 指令地址:

    • 执行方法是 Java 方法:程序计数会保存该方法对应的指令地址

    • 执行的方法是 Native 方法:[程序计数器将会被置为空 (Undefined)]{.red}

      :::info

      简单来说 Native 方法就是本地方法,是不采用 Java 实现的外部方法,之后在本地方法栈详细介绍

      :::

  • 实质:

    • 程序计数器是 Java 虚拟机中 [运行速度最快,空间较小的内存区域]{.red}

    • Java 虚拟机中的程序计数器是对处理器中的程序计数器的抽象模拟

  • 特点::

    • [每个线程都拥有独立的程序计数器]{.red}

    • [每个线程都是不可以访问其余线程的空间的:线程间不可以直接相互通信]{.red}

      :::danger

      注:操作系统中进程中的每个线程都是直接相互通信的,进程之间才是相互隔离的

      :::

    • [程序计数器区域没有垃圾回收机制也没有 OutOfMemory 异常]{.red}

为什么要使用程序计数寄存器?

  • 前提:Java 多线程采用线程轮流切换,分配处理器执行时间的方式实现的(时间片轮转法?)
    • 第一个原因:多线程切换
      • 其余线程抢占当前线程的处理器使用权执行任务
      • 其余线程执行任务结束之后,之前被抢占的线程想要继续执行
      • [如果没有程序计数器加以保存]{.blue},那么之前被抢占的线程就不可能知道从哪里开始继续执行了
    • 第二个原因:方法调用(不准确)
      • 被调用的方法执行结束了,执行引擎需要借助 [返回地址]{.red} 才能够回到此前的位置
      • 返回地址就是获取的当前程序计数器的值,确保方法调用结束后执行引擎能够返回

程序计数器为什么是线程私有的呢?

  • 其余线程抢占当前线程的处理器使用权执行任务
  • 其余线程执行任务结束之后,之前被抢占的线程想要继续执行
  • [如果所有线程共享同一个程序计数器,那么上一个线程存入程序计数器的字节码指令地址就会被下一个线程 覆盖]{.blue}
  • 那么之前被抢占的线程就不可能知道从哪里开始继续执行了

:::info

参考博客:

JVM 程序计数器

:::

Author: Fuyusakaiori
Link: http://example.com/2021/09/24/jvm/runtime/程序计数寄存器/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.