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

有时候,不是因为你没有能力,也不是因为你缺少勇气,只是因为你付出的努力还太少,所以,成功便不会走向你。而你所需要做的,就是坚定你的梦想,你的目标,你的未来,然后以不达目的誓不罢休的那股劲,去付出你的努力,成功就会慢慢向你靠近。

导读:本篇文章讲解 JVM之运行时数据区和程序计数器,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、运行时数据区

1、内部结构

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

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

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

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

1、PC Register介绍

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

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

2、执行流程

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

/**程序计数器 */
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寄存器的值来明确下一条应该执行什么样的字节码指令

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/148649.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!