在计算机的体系结构中:
程序计数器(Program Counter),通常缩写为 PC,是计算机体系结构中的一个寄存器,用于存储下一条指令的地址。程序计数器是控制单元的一部分,它的作用是确保程序能够按正确的顺序执行指令。
以下是程序计数器的一些关键特性
1.指令定位
程序计数器总是指向CPU中下一条要执行的指令内存地址。
2.顺序执行
在大多数情况下,CPU会从程序计数器指定的地址获取指令,执行该指令,然后自动递增程序计数器的值,以便指向下一条指令。
3.分支和跳转
这也是很重要的一点,当程序执行到如 goto
、jmp
(无条件跳转),if-else
(条件分支)或 case等分支和跳转指令时,程序计数器的值会根据需要更新为非顺序的地址。
4.中断处理
当处理器接收到中断信号时,当前程序计数器的值可能会被保存,以便中断处理完成后能够恢复执行。
5.寄存器
程序计数器是一个特殊的寄存器,但它通常与其他通用寄存器分开,因为它由控制单元特别管理。
总结:
在计算机体系结构中的程序计数器(PC寄存器)是实现程序流程控制的关键组件,它确保了程序能够按照预定的顺序执行指令,同时也能够灵活地处理分支和子程序调用。在现代处理器设计中,程序计数器的概念可能被集成到更复杂的控制逻辑中,但其基本功能和目的保持不变。
在JVM中
介绍
在Java虚拟机(JVM)中,程序计数器(Program Counter Register,PCR)是一个较小的内存区域,它的作用与计算机CPU中的程序计数器类似。JVM的程序计数器记录了当前执行的字节码指令的地址,或者说是指向方法区中下一条要执行的字节码指令的指针。
位置
程序计数器存放在运行时数据区中,是JVM的一个重要组成部分,程序计数器在JVM中的内存位置如图所示。
以下是程序计数器的一些关键特性
1.线程私有
每个线程都有自己的程序计数器,是不被其他线程干扰和共享的,因此可以独立地执行字节码指令流,这是JVM实现多线程执行的一个关键部分,满足线程安全。
2.字节码执行
由于程序计数器会保存下一个指令的地址或者是存放方法区中下一条指令的指针,因此JVM的执行引擎会根据程序计数器的当前值来获取下一条字节码指令,并执行它。
3.分支和跳转
和计算机体系结构中的程序计数器类似,当执行到字节码中的分支或跳转指令时,程序计数器会更新为跳转目标指令的地址。
4.方法调用和返回
当线程调用一个方法时,程序计数器会更新为新方法的第一条指令的地址。当方法正常返回时,程序计数器会恢复到调用方法中的下一条指令。
这里给出一个例子便于理解:
public class Main {
public static void test(){
System.out.println("我不想上班!!!!!!!");
}
public static void main(String[] args) {
System.out.println("今天的心情ovo");
System.out.println("======================");
test();
}
}
我们将代码编译后,在target目录下找到对应的类(Main)并且输入 javap - v 类名.class 命令
查看结果如下
5.异常处理
和跳转类似,在发生异常时,JVM会更新程序计数器以跳转到相应的异常处理器。
6.上下文切换
当线程上下文切换时,程序计数器存储当前线程的执行位置,以便之后能够恢复执行。这里举一个例子,当一个线程还没有执行完,但是cpu分配给此线程的时间片已经用完了,第二个 线程将会被执行,那么当第二个线程执行完后如何找到前者的线程执行到哪里,其实就是程序计数器发挥了作用。
7.内存大小
JVM规范规定程序计数器是线程私有的,因此不会发生线程安全问题,并且不需要是固定的内存大小,因为JVM规范没有对程序计数器的大小进行限制。
8.不需要垃圾回收
JVM的垃圾回收几乎只发生在堆中,而由于程序计数器只是存储了下一条要执行的字节码指令的地址,因此它不会对JVM内存产生垃圾回收的压力。
总结:
程序计数器是JVM实现方法调用和返回机制的关键,它使得线程能够在执行Java代码和本地代码之间进行切换,同时保持执行的连续性和线程之间的独立性。