JVM(HotSpot):程序计数器(Program Counter Register)

文章目录

一、内存结构图

二、案例解读

我们使用javap对字节码进行反编译,来看下程序计数器怎么体现的。

IDEA写一个简单的Java代码

反编译命令
javap -verbose InitTest.class

java 复制代码
$ javap -verbose InitTest.class
Classfile /E:/workspace/JVMDemo/out/production/chapter01/com/rh/java/InitTest.class
  Last modified 2024-9-23; size 491 bytes
  MD5 checksum 56fd724ef01f37a20b2872002edd43cd
  Compiled from "InitTest.java"
public class com.rh.java.InitTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #4.#23         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#24         // com/rh/java/InitTest.a:I
   #3 = Class              #25            // com/rh/java/InitTest
   #4 = Class              #26            // java/lang/Object
   #5 = Utf8               a
   #6 = Utf8               I
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/rh/java/InitTest;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Utf8               args
  #17 = Utf8               [Ljava/lang/String;
  #18 = Utf8               i
  #19 = Utf8               j
  #20 = Utf8               k
  #21 = Utf8               SourceFile
  #22 = Utf8               InitTest.java
  #23 = NameAndType        #7:#8          // "<init>":()V
  #24 = NameAndType        #5:#6          // a:I
  #25 = Utf8               com/rh/java/InitTest
  #26 = Utf8               java/lang/Object
{
  public int a;
    descriptor: I
    flags: ACC_PUBLIC

  public com.rh.java.InitTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: bipush        8
         7: putfield      #2                  // Field a:I
        10: return
      LineNumberTable:
        line 3: 0
        line 4: 4
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      11     0  this   Lcom/rh/java/InitTest;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=4, args_size=1
         0: bipush        10
         2: istore_1
         3: bipush        20
         5: istore_2
         6: iload_1
         7: iload_2
         8: iadd
         9: istore_3
        10: return
      LineNumberTable:
        line 7: 0
        line 8: 3
        line 9: 6
        line 10: 10
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      11     0  args   [Ljava/lang/String;
            3       8     1     i   I
            6       5     2     j   I
           10       1     3     k   I
}
SourceFile: "InitTest.java"

类似下图,最左边的序号,我们可以简单的理解为jvm指令的内存地址。

三、工作流程

Java程序的运行流程大概如下

解释器,通过程序计数器,拿到指令的内存地址,从而获取到需要执行的指令

然后,解释器把指令翻译成机器码,CPU才能执行对应的机器码。

简单的理解为,当前程序运行到哪一行代码,就看程序计数器记录的指令地址。

而在物理硬件上,程序计数器是通过什么实现的了?

是通过CPU中的寄存器部分实现的效果,寄存器是CPU中运行速度最快的部分。

四、特点

1、线程私有的

每个线程都会有个属于自己的程序计数器。

2、不会存在内存溢出异常

相关推荐
云和数据.ChenGuang2 小时前
Python 常见特殊方法详解:__new__、__init__、__del__、__str__、__repr__ 与 __getattribute__
开发语言·人工智能·python·1024程序员节
xyouyuweizhu2 小时前
字节流与字符流:Java IO 的两条主线该怎么选
java·开发语言·python
迪菲赫尔曼2 小时前
【基础篇 04】第一次使用终端:命令在哪里输入,电脑现在又“站”在哪里?
python·yolo·目标检测
qianbo_insist3 小时前
# 在 Qwen3.5-2B 上把 GDN-1 无损换成 GDN-2:一次完整的架构手术实验(负结果)
人工智能·pytorch·python·架构
多弗朗皮卡丘3 小时前
C++的IO流
开发语言·c++·io流·文件io流
骑着蜗牛撵大象3273 小时前
AI Agent 工程化开发实战(三):用 StateGraph 给智能体搭一条可回放的状态流水线
java·开发语言·jvm·ai·状态管理·langgraph·stategraph
itmigrate3 小时前
Rust 里的所有权误区:不是不写 clone 就叫高性能
开发语言·后端·rust
Brilliantwxx3 小时前
【Linux】 文件访问与路径解析:目录、文件名、dentry、路径缓冲与 dcache 全解析
linux·运维·服务器·开发语言·spring
摇滚侠4 小时前
《On Java 中文版 基础卷》阅读笔记 初始化和清理 08
java·开发语言·笔记
xiangyun614 小时前
C++ 手撕 shared_ptr:引用计数与控制块到底长什么样?
开发语言·c++·算法·面试·stl