什么是程序计数器
背景:
相信学过计算机组成原理的同学都知道,CPU内部的寄存器中就包含一个程序计数器(x86下为eip寄存器,ARM下为R15寄存器),存放程序执行的下一条指令地址。程序每次执行时,CPU都会自动存储下一条指令的地址,以便下次继续执行。
JVM偷学了CPU:
JVM也是参考了CPU的程序计数器,自己设计了一个程序计数器,用于存储JVM当前执行bytecode的地址(字节码指令地址)。
程序计数器记录当前线程正在执行的字节码地址。
程序计数器是线程隔离的。每一个线程在工作的时候都有一个独立的计数器。
什么是字节码指令地址
编译下面的代码:
public class Test1 {
public int test(){
int a = 1000;
int b = 2000;
int c = 3000;
return a+b+c;
}
}
利用jclasslib查看字节码:
右边那一块就是字节码地址了
为什么要存储这个字节码指令地址呢?
由于CPU的上下文切换,导致不停地切换每条线程,就会出现线程经常中断或回复;
当CPU上下文切换,线程中断时,必须准确记录每条线程的执行位置,即记录当前线程执行的字节码指令地址;
当线程恢复时,再从中断的位置继续执行。
为了达到这样一个效果,JVM为每条线程都分配一个程序计数器。
这样每条线程都可以独立计算,故当出现CPU上下文切换时,线程中断,程序记录器记录了当前的字节码指令地址,线程恢复,就从中断的位置继续执行。
举个例子:
CPU并发2条线程,CPU首先执行线程A,假设线程A执行到第3行时,CPU突然切换执行线程B,那么线程A就处于中断状态,线程A的计数器记录下一个字节码地址4;
当线程B执行到第10行的时候,CPU突然切换执行线程A,同理线程B中断,并线程B记录下一个字节码地址11,
被切换的线程A恢复后,从字节码地址4开始执行。
由此可见,如果没有程序计数器的话,在CPU上下文切换时,多线程计算必定乱成一团。
程序计数器的特点
- 每条线程都有自己的程序计数器,而且是线程私有的,它的生命周期