# JVM程序计数器

JDK版本:1.8

# 1、程序计数器(Program Counter Register )

JVM中的程序计数寄存器(Program Counter Register)中,Register的命名源于CPU的寄存器,寄存器存储指令相关的现场信息。CPU只有把数据装载到寄存器才能够运行。这里并非是广义上所指的物理寄存器,或许将其翻译为PC计数器(或指令计数器)会更加贴切(也称为程序钩子),并且也不容易引起一些不必要的误会。JVM中的PC寄存器是对物理PC寄存器的一种抽象模拟。

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

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

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

  • 任何事件一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址,如果是在执行native方法,则是未指定值(undefined)。

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

  • 字节码解释器工作时就是通过改变PC寄存器的值来选取下一条需要执行的字节码指令。

  • PC寄存器是唯一一个在Java虚拟机规范中没有规定任何OutOfMemeoryError情况的区域。


# 2、PC寄存器代码举例

public class ProgramCounterRegister {public static void main(String[] args) {int minus = minus();System.out.println("minus = " + minus);}private static int minus() {int i = 3;int j = 4;return j - i;}}

字节码文件:

0: iconst_3
1: istore_1
2: iconst_4
3: istore_2
4: iload_1
5: iload_2
6: isub
7: ireturn

# 3、PC寄存器的作用

在多线程的情况下,CPU需要不停的切换各个线程,当从A线程切换到B线程之后,CPU需要知道接着从哪里开始继续执行代码。

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


# 4、PC寄存器为什么被设定为线程私有

所谓的多线程,其实CPU在一个时间点只能执行某一个线程的方法,也就是说CPU需要在多线程之间不停地做任务切换,这样必然会导致经常中断或恢复。为了能够准确地记录各个线程正在执行的当前字节码指令地址,JVM会为每个线程都分配一个PC寄存器,这样就能解决各个线程之间的独立计算,也不会出现线程之间互相干扰的情况。

由于CPU时间片轮限制,众多线程在并发执行的过程中,任何一个确定的时刻,一个处理器或者多核处理器中的一个内核,只会执行某个线程中的一条字节码指令。这样也会导致中断或恢复,为了确保CPU在线程之间的切换分毫无差,JVM在每个线程创建之后,都会产生线程独有的PC计数器和栈帧,保证各个线程之间互不影响。


# 5、CPU时间片

CPU时间片:CPU分配给各个应用程序的执行时间,每个线程被分配一个时间段,称作它的时间片。

在宏观上:开发者可以同时打开多个应用程序,每个程序互不影响,并行执行。

在微观上:由于只有一个CPU,一次只能处理程序要求的一部分,如何公平分配CPU,此时就需要借助时间片,让每个程序轮流并行执行。

JVM - 程序计数器相关推荐

  1. JVM程序计数器,虚拟机栈,本地方法栈

    程序计数器 它记录了程序执行字节码的行号和指令,字节码解释器的工作就是改变程序计数器的值,切换下一条需要执行的指令(分支,循环,跳转,异常等).java虚拟机是多线程通过轮流切换CPU时间片的方式实现 ...

  2. JVM各内存区域存放内容

    一.方法区存放内容: 1.类的全限定名(类的全路径名). 2.类的直接超类的权全限定名(如果这个类是Object,则它没有超类). 3.类的类型(类或接口). 4.类的访问修饰符,public,abs ...

  3. 第五篇:初识JVM,JVM自动内存管理

    文章目录 一.前言 1.1 计算机==>操作系统==>JVM 1.1.1 虚拟与实体(对上图的结构层次分析) 1.1.2 Java程序执行(对上图的箭头流程分析) 二.JVM内存空间与参数 ...

  4. java垃圾回收策论_深入理解 Java 虚拟机【3】垃圾收集策略与算法

    作者:杨立滨 链接:https://github.com/yanglbme/jvm 程序计数器.虚拟机栈.本地方法栈随线程而生,也随线程而灭:栈帧随着方法的开始而入栈,随着方法的结束而出栈.这几个区域 ...

  5. Java面试遇到的问题(更新中---)

    一.千峰学员遇到的面试题总结 1. ArrayList和linkedlist 使用场景? concurrenthashmap为什么是线程安全的? cpu的调度算法? redis为什么是单线程的还那么多 ...

  6. java面试题目前为止全内容收集

    目录 java异常处理 Exception类的层次 Java内置异常类 异常方法 JAVA基础 JAVA反射 什么是反射? 为什么需要反射? JAVA接口 为什么要用接口 JAVA构造方法 JAVA集 ...

  7. 一篇文章带你速度过完Java基础

    Java基础 Java 数据类型 基本数据类型 包装数据类型 引用类型 数据类型转换 缓存池 经典面试题1 经典面试题2 变量 内存分析 作用范围 生命周期 Java 关键字 Java关键字汇总 fi ...

  8. 《深入理解JAVA虚拟机》详细解读(第二章 ):JAVA内存区域与内存溢出异常

    目录 一.JAVA内存区域与内存溢出异常 1. 概述 2. 运行时数据区域 2.1 程序计数器 2.2 Java虚拟机栈 2.3本地方法栈 2.4 堆 2.5 方法区 2.6 运行时常量池 2.7直接 ...

  9. JVM - 结合代码示例彻底搞懂Java内存区域_线程栈 | 本地方法栈 | 程序计数器

    文章目录 Pre 运行时数据区总览 线程栈 概要 栈内部主要组成部分 局部变量 操作数栈 动态链接 方法出口 小结 程序计数器 本地方法栈 附 测试demo javap JVM字节码指令集手册 Pre ...

最新文章

  1. SVN详解-linux+windows
  2. [原]missing #39;;#39; before #39;namesapce#39;错误的解决
  3. Android 4.0 Notification
  4. python与rpc服务
  5. 几种主要的Linux版本之间的比较
  6. staem被盗_如何检查照片是否被盗
  7. 北妈每日一题:到底谁养了我的鱼!
  8. 初探nginx架构(100%)
  9. C#跨窗体传值的几种方法分析第三版
  10. 实用分层模板,分分钟了解UI界面设计基本原则!
  11. 解决Kscope中文乱码问题
  12. python优雅编程_Python——traceback的优雅处理
  13. Java文件的写入与读出
  14. (9.19更新:八戒退款) 砸进七万块,没想到你是这样的猪八戒网
  15. 高手的作用在于解决难题
  16. [已解决]罗技鼠标驱动打不开问题
  17. 2022年GPS广播星历精密星历如何下载
  18. ie11 java提示升级,解决IE11安装升级失败和在安装前需要更新的问题
  19. 借助C++类结构计算矩形面积(矩形类)
  20. 系统架构师进阶(Believe Youself)

热门文章

  1. 网站性能调优实战-学相伴KuangStudy
  2. 基于 mysql时序_几个时序数据库
  3. WORD快捷键小技巧
  4. Python 机器人魔鬼的步伐中居然隐藏着杨辉三角形
  5. 从“弄潮儿”到“追风者”,康师傅还能引领市场吗?
  6. vue项目启动后终端显示localhost和ip访问地址
  7. tinyxml 内存泄露_tinyxml 用法
  8. [转]写一个块设备驱动(第六章)
  9. 基于SSM的个人饮食健康运动作息时间数据分析管理系统(javaweb-php-asp.netC#-j2ee)包含数据统计分析建议
  10. linux日志文件存在哪里,linux系统日志在哪里