文章目录
- 一、内存结构图
- 二、案例解读
- 三、工作流程
- 四、特点
一、内存结构图
二、案例解读
我们使用javap
对字节码进行反编译,来看下程序计数器怎么体现的。
IDEA
写一个简单的Java
代码
反编译命令
javap -verbose InitTest.class
$ 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、不会存在内存溢出异常