前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >JVM之运行时数据区和程序计数器

JVM之运行时数据区和程序计数器

作者头像
冬天vs不冷
发布2025-01-20 22:08:58
发布2025-01-20 22:08:58
7900
代码可运行
举报
文章被收录于专栏:springbootspringboot
运行总次数:0
代码可运行

一、运行时数据区

1、内部结构

java虚拟机定了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动儿创建,随着虚拟机退出而销毁。另外一些则是与线程一一对应的,这些与线程对应的数据区域会随着线程的开始和结束而创建和销毁。

灰色的为单独线程私有的,红色的为多个线程共享的。

各个线程:独有包括程序计数器、栈、本地栈 线程间共享:堆、堆外内存(永久代或元空间、代码缓存)

二、程序计数器(PC寄存器)

1、PC Register介绍

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

  • 它是一块很小的内存空间,几乎可以忽略不计。也是运行速度最快的存储区域
  • 在JVM规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致
  • 任何时间一个线程都只有一个方法再执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的java方法的JVM指定地址;或者,如果是执行native方法,则是未指定值(undefined)
  • 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令
  • 它是唯一一个在java虚拟机规范中没有规定任何OutOtMemoryError情况的区域

2、执行流程

我们首先写一个简单的代码

代码语言:javascript
代码运行次数:0
复制
/**程序计数器 */
public class PCRegisterTest {
    public static void main(String[] args) {
        int i = 10;
        int j = 20;
        int k = i + j;
    }
}

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

指令地址不连续的原因:

  • 上面的0,2,3,5是每条指令的地址(偏移量),地址不连续的原因是:每条指令的长度是不确定的,从单字节到多字节(诸如tableswitch 这样的指令自身就是变长的)
  • JVM的指令包括操作码、操作数两部分,操作码固定都是1字节,最多256条指令。但不同的操作的操作码有不同的操作数,例如上述的istore1,istore2等都没有操作数,所以只占1字节。bipush有一个8bit的操作数,因此指令长度为2

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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、运行时数据区
    • 1、内部结构
  • 二、程序计数器(PC寄存器)
    • 1、PC Register介绍
    • 2、执行流程
    • 3、为什么使用PC寄存器记录当前线程执行地址?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档