【JVM 02-JVM内存结构之-程序计数器】

程序计数器 笔记记录

  • [1. 定义](#1. 定义)
  • [2. 作用](#2. 作用)
  • [3. 特点](#3. 特点)
  • [4. 拓展理解](#4. 拓展理解)
    • [4.1 PC寄存器存储字节码指令地址有什么用?](#4.1 PC寄存器存储字节码指令地址有什么用?)
    • [4.2 PC寄存器为什么被设定为线程私有的?](#4.2 PC寄存器为什么被设定为线程私有的?)
    • [4.3 为什么执行native方法时,是undefined?](#4.3 为什么执行native方法时,是undefined?)

学习资料来源-b站黑马JVM& 尚硅谷JVM精讲与GC调优

1. 定义

Program Counter Register 程序计数器

当执行一条指令时,首先需要根据PC中存放的指令地址 ,将指令由内存取到指令寄存器中,此过程称为"取指令"。与此同时,PC中的地址或自动加1或由转移指针给出下一条指令的地址。此后经过分析指令,执行指令。完成第一条指令的执行,而后根据PC取出第二条指令的地址,如此循环,执行每一条指令。

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

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

2. 作用

可以看作是当前线程所执行的字节码的行号指示器用于存储当前线程正在执行的 Java 方法的 JVM 指令地址 。如果线程执行的是 Native 方法,计数器值为 null。是唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域,生命周期与线程相同。来源于小林coding解释

3. 特点

  • 线程私有,CPU给多个线程分配时间片,线程执行到某个位置的时候,可能时间片用完了,这时候就需要程序计数器去记录当前运行的指令的下一条,这样的话线程恢复后,就可以直接接着上一次执行的位置继续执行。每个线程都有自己的程序计数器。
  • 唯一一个不会出现内存溢出的部分
    ● 它是一块很小的内存空间,几乎可以忽略不记。也是运行速度最快的存储区域。不会随着程序的运行需要更大的空间。
    ● 在JVM规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致。

4. 拓展理解

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

使用PC寄存器存储字节码指令地址有什么用呢?
(为什么使用PC寄存器记录当前线程的执行地址呢?)

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

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

● 通俗解释就是,不同的线程执行是有分配的时间片的,假设A线程执行一半时间片用完了就轮到其他线程了,其他线程可能执行完了以后,A线程这时候执行肯定要依赖程序计数器的标记在哪里继续执行,总不能直接执行。

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

PC寄存器为什么会被设定为线程私有?

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

4.3 为什么执行native方法时,是undefined?

任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址 ;或者,如果是在执行native方法,则是未指定值(undefined)。为什么?
native 本地方法是大多是通过C实现,并未编译成需要执行的字节码指令,所以在计数器中当然是空(undefined)。说白了,native已经出了虚拟机管控的范围了。

相关推荐
2301_815901973 小时前
SQL如何将多行记录聚合成逗号分隔字符串_GROUP_CONCAT技巧
jvm·数据库·python
zjy277774 小时前
Layui tab选项卡如何动态根据ID值进行程序化切换
jvm·数据库·python
m0_602857764 小时前
Redis如何修复槽位分配重叠的脏状态_使用redis-cli --cluster fix工具扫描并修复不一致的Slot
jvm·数据库·python
2301_766283444 小时前
怎样开启phpMyAdmin的操作审计日志_记录每条执行的SQL
jvm·数据库·python
zhoutongsheng5 小时前
如何解决ORA-01078参数文件错误_pfile与spfile互相创建恢复
jvm·数据库·python
2401_824222695 小时前
HTML怎么标注字数限制提示_HTML实时字数统计占位【详解】
jvm·数据库·python
littleM6 小时前
深度拆解 HermesAgent(五):记忆系统与用户建模
jvm·人工智能·架构·ai编程
dfdfadffa6 小时前
如何创建仅在首次订阅时执行一次计算的 RxJS 懒加载 Observable
jvm·数据库·python
m0_624578596 小时前
SQL分组后如何计算移动平均值_利用窗口函数AVG配合ROWS
jvm·数据库·python
2401_824222697 小时前
如何修复待办事项列表无法添加任务的 JavaScript 错误
jvm·数据库·python