博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java寄存器_【JAVA虚拟机(JVM)精髓】13-程序计数寄存器详解
阅读量:5742 次
发布时间:2019-06-18

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

持续更新JVM相关知识,敬请关注:Java虚拟机精髓专栏​zhuanlan.zhihu.com68346032805b04f621d5ef0011e0acb7.png

程序计数寄存器(Program Counter Register),关于他的相关内容,最权威的当然是官方的介绍,大家可以从下面的网址直接查看Oracle官方的文档,这里是最准确全面的解释:The Java® Virtual Machine Specification​docs.oracle.com

如果英文不好,无法透彻理解,那么请继续往下看:

程序计数寄存器,英文是Program Counter Register,叫起来有些长,绕口,平时也会简化叫做程序计数器或PC寄存器。

这里叫他寄存器,和硬件层面的物理寄存器并不是一回事儿,他只是对物理寄存器的一种软件模拟。其实叫他程序计数器更加的合理,免得发生不必要的混淆。也可以叫他钩子。

那么这个钩子钩的是什么呢?或者说他计数计的是什么数呢?

如上图,程序运行时是一个个线程执行,线程中有着要执行的一行行代码,这一个个钩子就勾着一行行的待执行代码,他也成为行号指示器,一行代码执行完了,下一行要执行哪个了,就由他来标记。说的官方一点儿,就是程序计数器,是用来存储指向下一条指令的地址,也就是将要执行的指令代码。程序计数器所占用的内存空间很小,可以忽略,他也是运行速度最快的存储区域。

程序计数器每个线程都独立有一份,随着线程的生命周期

同一时间,一个线程内只有一个方法在执行,称为当前方法,程序计数器就是存储着当前方法的JVM指令地址,如果执行的是native方法,则值是undefined

程序中所有的跳转、循环、异常处理等都依赖于程序技术器来完成

他是JAVA虚拟机规范中唯一一个没有规定任何内存溢出情况的区域

下面我们看个更直观的例子,首先我们先写一段代码,不多讲,谁都能看懂:

public static void main(String[] args) {

int i=1;

int j=2;

int k=i+j;

}

然后使用javap命令反编译class文件,得到如下内容:

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=4, args_size=1

0: iconst_1 //常量1 1: istore_1 //保存到索引为1的位置 2: iconst_2 //常量2 3: istore_2 //保存到索引为2的位置 4: iload_1 //取出索引位置1数据 5: iload_2 //取出索引位置2数据 6: iadd //做加法运算 7: istore_3 //结果保存到索引为3的位置 8: return //程序结束 LineNumberTable:

line 4: 0

line 5: 2

line 6: 4

line 7: 8

LocalVariableTable:

Start Length Slot Name Signature

0 9 0 args [Ljava/lang/String;

2 7 1 i I

4 5 2 j I

8 1 3 k I

我们可以看到,反编译后的程序执行过程,每一个执行过程前面都有一个数字,这些数字就是指令地址,也叫偏移地址,这也就是程序计数器所存储的结构,数字后面的内容叫做代码指令。

执行引擎根据程序计数器中的指令地址,来取出相应的操作指令去执行当前应该执行的操作。如下图所示:

面试时关于程序计数器经常会被问到一个问题,就是为什么要用程序计数器来存储指令地址呢?

如果你对上面的知识都听懂了,那么答案也很简单:

因为CPU的多核心在执行多线程程序时,并不是真的多个线程同时执行,而是在多个线程中快速的进行切换执行,因为同一时间只能操作一个线程,那么当切换回某个线程时,CPU需要明确知道程序执行到什么位置了,该从哪继续执行,那么这时候,就需要程序计数器来告诉他,下一条需要执行的指令地址是什么。

说到这里,再说一下CPU时间片的概念,我们日常在使用计算机时,同时会打开很多程序,无论是多个CPU还是一个CPU多核心,还是一个CPU单一核心,都可以做到如此,所有程序“同时”在运行。这里注意“同时”两个字我用了引号,那也就是说并非同时,根据上一节的知识我们知道,CPU同一时间只能处理一个线程,那么又是如果做到看似很多程序一起执行呢?

这就利用了一个叫做CPU时间片的概念,CPU给每个线程非配一段执行时间,时间到了就切换到下一个线程,由于CPU的主频非常高,切换速度非常快,以至于宏观上的感受就是程序一起在运行。实际微观层面,是轮流执行的。这个大家要理解。

转载地址:http://efnzx.baihongyu.com/

你可能感兴趣的文章
Jenkins与Docker的自动化CI/CD实战
查看>>
windows2008下的web配置ssl(4)
查看>>
Python初始基本数据类型
查看>>
比较 SLF4J 与 log4j
查看>>
Redmine Client for windows phone 7.5
查看>>
Mac Finder 自带FTP工具
查看>>
openSUSE 下修改DNS配置
查看>>
C#矩阵加法、取负、数乘、乘法的实现
查看>>
谭浩强《C++程序设计》书后习题 第十章-第十二章
查看>>
我的友情链接
查看>>
C#语言中对象数组到DataTable的转换
查看>>
Moto XT800(双卡手机)短信和电话服务的总结
查看>>
中国软件开发工程师之痛
查看>>
YUM仓库的两种网络提供方式
查看>>
【直播预告】云栖直播:阿里热修复产品HotFix2.0升级详解
查看>>
我的友情链接
查看>>
跟着石头哥哥学cocos2d-x(一)---2dx环境搭建 (win7)
查看>>
c# 程序只能运行一次(多次运行只能打开同一个程序) 并激活第一个实例,使其获得焦点,并在最前端显示....
查看>>
认识Html
查看>>
Sql 学习随笔
查看>>