11.JVM运行时数据区域之程序计数器

 

1.程序计数器概述

1.程序计数器又称为PC寄存器。
英文是Program Counter Register。程序计数器是软件的概念,是对物理的PC寄存器的一种模拟。
方法区,堆区存在垃圾回收机制。
PC寄存器,JVM栈区,本地方法栈不存在GC。
除了PC寄存器不会出现OOM之外,其他的区域都可能出现OOM。
PC寄存器既没有GC也没有OOM。
在这里插入图片描述
2.程序计数器的作用
PC寄存器用来存储下一条要执行的指令的地址。执行引擎根据PC寄存器里面的地址,执行指令,执行完成之后,再根据PC寄存器里面存储的地址,执行下一条指令。
在这里插入图片描述
3.PC寄存器是一块很小的内存空间。
在JVM规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致。
任何时间任何一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器存储的是当前线程正在执行的java方法的jvm指令地址。或者,如果执行的是native方法,则是未指定值(undefined)。
在这里插入图片描述
它是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError的区域。

在这里插入图片描述

2.PC寄存器理解例子

下面的代码编译成class文件之后,进行反编译。

public class PCRegisterTest {

    public static void main(String[] args) {
        int i = 10;
        int j = 20;
        int k = i + j;

        String s = "abc";
        System.out.println(i);
        System.out.println(k);

    }
}

可以得到如下图所示的代码(图中间部分):
第一列数字0,2,3称为指令地址(或者叫做偏移地址)。第二列称为操作指令。
PC寄存器存储的就是指令地址的值。比如图中的PC寄存器存储的指令地址是5。
执行引擎会根据PC寄存器中的指令地址,取到操作指令,然后翻译成机器指令,给CPU执行。
执行引擎在执行操作指令的过程中还会操作局部变量表、操作数栈。
在这里插入图片描述

3.PC寄存器的两个面试问题

问题1:使用PC寄存器存储字节码指令地址有什么用?为什么使用PC寄存器记录当前线程的执行地址?
当cpu不断的切换到各个线程执行,在切换回原来的线程之后,需要知道有个继续从哪里开始执行,所以需要PC寄存器存储下一条指令的地址。
在这里插入图片描述
问题2:PC寄存器为什么被设定为线程私有?
CPU从一个线程切换到另一个线程的时候,需要记录当前线程需要执行的下一条字节码指令地址,给每一个线程都分配一个PC寄存器,可以防止线程之间相互干扰。
在这里插入图片描述
如下图所示,有三个线程1,2,3。当CPU在这三个线程之间切换的时候,PC寄存器会存储各个线程的当前指令地址。
如果PC寄存器不是线程私有的,那么在从线程1切换到线程2的时候,PC寄存器保存的是线程1的下一条指令地址5;但是切换到2之后,PC寄存器的下一条指令地址值变成了7,这时候如果再切换到线程1,就找不到线程1的下一条指令地址5了。
在这里插入图片描述

posted @ 2020-11-18 10:19  跃小云  阅读(170)  评论(0编辑  收藏  举报