「JVM系统学习之路」运行时数据区概述和程序计数器( 二 )


作用PC寄存器 用来存储指向下一条指令的地址 , 以即将要执行的指令代码 。 由执行引擎读取下一条指令 。
「JVM系统学习之路」运行时数据区概述和程序计数器文章插图
举例说明通过写一个简单的代码演示:
/**程序计数器 */public class PCRegisterTest {public static void main(String[] args) {int i = 10;int j = 20;int k = i + j;}}复制代码将上面的 java 文件编译成字节码文件 , 然后执行 ` javap -c PCRegisterTest.class``, 通过控制台查看, 发现在字节码的左边有一个行号标识 , 它其实就是指令地址 , 用于指向当前执行到哪里 。
public static void main(java.lang.String[]);Code:0: bipush102: istore_13: bipush205: istore_26: iload_17: iload_28: iadd9: istore_310: return}复制代码通过PC寄存器 , 我们就可以知道当前程序执行到哪一步了
「JVM系统学习之路」运行时数据区概述和程序计数器文章插图
两个常见问题使用PC寄存器存储字节码指令地址有什么用呢?因为 CPU 需要不停地切换各个线程 , 这时候切换回来以后 , 就得知道接着从哪开始继续执行 。JVM的字节码解释器就需要通过改变 PC 寄存器 的值来明确下一条应该执行什么样的字节码指令 。
「JVM系统学习之路」运行时数据区概述和程序计数器文章插图
PC寄存器为什么被设定为私有的?我们都知道所谓的多线程在一个特定的时间段内只会执行其中某一个线程的方法 , CPU 会不停地做任务切换 , 这样必然导致经常中断或恢复 , 如何保证分毫无差呢? 为了能够准确地记录各个线程正在执行的当前字节码指令地址 , 最好的办法自然是为每一个线程都分配一个PC寄存器, 这样一来各个线程之间便可以进行独立计算 , 从而不会出现相互干扰的情况 。由于 CPU 时间片轮限制 , 众多线程在并发执行过程中 , 任何一个确定的时刻 , 一个处理器或者多核处理器中的一个内核 , 只会执行某个线程中的一条指令 。这样必然导致经常中断或恢复 , 如何保证分毫无差呢?每个线程在创建后 , 都会产生自己的程序计数器和栈帧 , 程序计数器在各个线程之间互不影响 。
「JVM系统学习之路」运行时数据区概述和程序计数器文章插图
CPU时间片CPU 时间片即 CPU 分配给各个程序的时间 , 每个线程被分配一个时间段 , 称作它的时间片 。在宏观上:我们可以同时打开多个应用程序 , 每个程序并行不悖 , 同时运行 。但在微观上:由于只有一个 CPU , 一次只能处理程序要求的一部分 , 如何处理公平 , 一种方法就是引入时间片 , 每个程序轮流执行 。
「JVM系统学习之路」运行时数据区概述和程序计数器文章插图
总结本篇回顾 , 第一部分为运行时数据区 , 第二部分就是程序计数器 。 JVM 能高效稳定运行, 主要是 JVM 内存布局规定了 Java 在运行过程中内存申请、分配、管理的策略 。 接下来会通过很多的章节讲述运行时数据区下的各个区 。 还需要了解PC寄存器 用来存储指向下一条指令的地址 , 也即将要执行的指令代码 。 由执行引擎读取下一条指令 。
【「JVM系统学习之路」运行时数据区概述和程序计数器】作者:山间木匠链接:来源:掘金著作权归作者所有 。 商业转载请联系作者获得授权 , 非商业转载请注明出处 。