【JVM】运行时数据区、程序计数器


🐌个人主页: 🐌 叶落闲庭

💨我的专栏:💨
c语言
数据结构
javaEE
操作系统
Redis

石可破也,而不可夺坚;丹可磨也,而不可夺赤。


JVM

  • [一、 运行时数据区](#一、 运行时数据区)
  • [二、 程序计数器](#二、 程序计数器)

类加载器将字节码文件加载到内存当中的时候,会用到两块内存区域:一块是方法区、另外一块叫做堆区,这两块区域都属于Java虚拟机管理的内存,由于JVN在运行过程中会去使用这块内存,所以就称之为运行时数据区域,它的职责除了保存字节码信息之外,还可以将创建出来的对象放到这块内存区域。

一、 运行时数据区

通常把运行时数据区换分为两类,一类是线程不共享(程序计数器、Java虚拟机栈、本地方法栈)、一类是线程共享(方法区、堆区)

  • 线程不共享指的是每当创建一个线程之后,每个线程里都会有一份程序计数器、Java虚拟机栈和本地方法栈对应的数据,该数据由本线程维护,其他线程无法访问本线程对应的数据,所以数据无法做到共享,但是整体安全性比较高,当线程结束后,将整个线程回收掉,这块内存区域也会得到释放。
  • 线程共享指的是只要往方法区/堆区放入数据,每个线程都可以获取这些数据并去使用,虽然数据可以共享,但是存在安全性问题

二、 程序计数器

程序计数器(Program Counter Register)也叫PC寄存器,每个线程会通过程序计数器记录当前要执行的的字节码指令的地址。

  • 属于线程独自拥有的数据,里面存放了接下来要执行的字节码指令的内存地址。
  • 字节码指令最初是保存在字节码文件中的,类加载器把字节码文件读取到内存之后,这个指令也会保存到内存当中,每一行指令都有对应的内存地址。
  • 字节码指令最终是要被解释器解释执行的,所以解释器就需要知道要执行的字节码指令在哪,而程序计数器就恰恰保存了字节码指令的地址,解释器只需要通过程序计数器就能得到字节码指令的内存地址。

程序计数器的案例

  • 源代码
java 复制代码
public static void main(String[] args) {
        int i = 0;
        if (i == 0) {
            i--;
        }
        i++;
    }
  • 字节码指令
Java 复制代码
0 iconst_0
1 istore_1
2 iload_1
3 ifne 9 (+6)
6 iinc 1 by -1
9 iinc 1 by 1
12 return

将局部变量 i 赋值为0

  • iconst_0
  • istore_1

判断 i 和0是否相等,如果不相等,跳转到指令9的位置

  • iload_1
  • ifne 9 (+6)

i 和 0 相等,就将i减1:

  • iinc 1 by -1

i 和 0 不相等,就将 i 加1:

  • iinc 1 by 1

接下来这个字节码指令就会进入类的加载阶段被加载到内存中,原来字节码指令的每条指令前都有一个偏移量,加载到内存后,偏移量会被替换成地址,每一条字节码指令都会有自己的内存地址,在代码执行过程中,程序计数器会记录下一行字节码指令的地址。执行完当前指令之后,虚拟机的执行引擎根据程序计数器执行下一行指令。
程序计数器可以控制程序指令的进行,实现分支、跳转、异常等逻辑。
在多线程执行情况下,Jva虚拟机需要通过程序计数器记录CPU切换前解释执行到那一句指令并继续解释运行。


相关推荐
未若君雅裁2 小时前
JVM基础总结
java·jvm·java-ee
心态特好3 小时前
JVM 如何判断‘对象 / 类该回收
jvm
鲸沉梦落3 小时前
JVM类加载
java·jvm
EAIReport5 小时前
自动化报告生成产品内嵌OA/BI平台:解决传统报告痛点的技术方案
java·jvm·自动化
没有bug.的程序员13 小时前
Java 字节码:看懂 JVM 的“机器语言“
java·jvm·python·spring·微服务
白露与泡影13 小时前
2025年BAT面试题汇总:JVM+Spring+Dubbo+Redis+并发编程
jvm·spring·dubbo
-大头.13 小时前
深入理解 Java 内存区域与 JVM 运行机制
java·jvm
没有bug.的程序员13 小时前
JVM 整体架构:一套虚拟机的心脏与血管
java·jvm·spring boot·spring cloud·架构
IUGEI16 小时前
【后端开发笔记】JVM底层原理-垃圾回收篇
java·jvm·笔记·后端