JVM-程序计数器
发布日期:2022-03-15 19:31:00 浏览次数:3 分类:技术文章

本文共 1452 字,大约阅读时间需要 4 分钟。

JVM中的程序计数寄存器(Program Counter Register)中,Register的命名源于CPU的寄存器,寄存器存储指令相关的现场信息。CPU只有把数据装载到寄存器才能够运行。

这里,并非是广义上所指的物理寄存器,或许将其翻译为PC计数器(或指令计数器)会更加贴切(也称为程序钩子),并且也不容易引起一些不必要的误会。JVM中的PC寄存器是对物理PC寄存器的一种抽象模拟。

本人更愿意称呼:行号指示器

它是一块很小的内存空间,几乎可以忽略不记。也是运行速度最快的存储区域。

在JVM规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致。

任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址;或者,如果是在执行native方法(对应本地方法栈),则是未指定(undefned)。

它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。

它是唯一一个在Java虚拟机规范中没有规定任何outotMemoryError情况的区域。

作用

 PC寄存器用来存储指向下一条指令的地址,也即将要执行的指令代码。由执行引擎读取下一条指令。

例子

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

 然后将代码进行编译成字节码文件,我们再次查看 ,发现在字节码的左边有一个行号标识,它其实就是指令地址(PC),用于指向当前执行到哪里。右边为操作指令

0: bipush        10  //放入10

2: istore_1            //将10放入栈中为1的位置
3: bipush        20  //放入20
5: istore_2            //将20放入栈中为2的位置
6: iload_1             //装载栈中位置为1的数
7: iload_2             //装载栈中位置为2的数
8: iadd                  //作加法
9: istore_3            //将结果放入栈中为3的位置
10: return             //返回

 

使用PC寄存器存储字节码指令地址有什么用呢

&&

为什么使用PC寄存器记录当前线程的执行地址?

因为CPU需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行。

JVM的字节码解释器就需要通过改变PC寄存器的值来明确下一条应该执行什么样的字节码指令。

PC寄存器为什么被设定为私有的?

我们都知道所谓的多线程在一个特定的时间段内只会执行其中某一个线程的方法,CPU会不停地做任务切换,这样必然导致经常中断或恢复,如何保证分毫无差呢?为了能够准确地记录各个线程正在执行的当前字节码指令地址,最好的办法自然是为每一个线程都分配一个PC寄存器,这样一来各个线程之间便可以进行独立计算,从而不会出现相互干扰的情况。

由于CPU时间片轮限制,众多线程在并发执行过程中,任何一个确定的时刻,一个处理器或者多核处理器中的一个内核,只会执行某个线程中的一条指令。

这样必然导致经常中断或恢复,如何保证分毫无差呢?每个线程在创建后,都会产生自己的程序计数器和栈帧,程序计数器在各个线程之间互不影响。

转载地址:https://blog.csdn.net/weixin_58104242/article/details/122574669 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:JVM- 如何判断两个class对象是否相同 && 类的主动使用和被动使用
下一篇:JVM- 线程

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2023年05月31日 07时39分17秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

最新文章

FORMAT函数的解释 2020-01-11 03:25:25
话剧的一般内容及一份话剧台词 2020-01-11 03:25:24
Android根build.gradle中buildscript和allprojects的作用和区别是什么 2020-01-11 03:25:20
Android:gradle 插件版本号与gradle 版本号对应关系 2020-01-11 03:25:20
android 电量性能优化 2020-01-11 03:25:20
SourceTree修改Git账号密码 2020-01-11 03:25:20
常见电脑故障自查自修技巧 2020-01-11 03:25:14
C++ 10.28 2020-01-11 03:25:12
C++ 10.29 2020-01-11 03:25:13
C++ 11.09 2020-01-11 03:25:13
MATLAB中的复杂矩阵输入问题 2020-01-11 03:25:13
面试题 +++++ 2020-01-11 03:25:13
2021-01-24 2020-01-11 03:25:13
day 1 2020-01-11 03:25:12
Hibernate缓存机制详解 2020-01-11 03:25:12
day 2 2020-01-11 03:25:12
C++ 10.26 2020-01-11 03:25:12
day 3 2020-01-11 03:25:12
C++ 10.27 2020-01-11 03:25:12
遍历Map的三种方式 2020-01-11 03:25:11