0 运行时数据区结构
1 运行时数据区&程序计数器
当一个class文件被类加载器Loading到JVM中,经过Linking和Initialization后,在运行时数据区的方法区Method Area产生了一个Class对象,这个Class对象的普通变量和static修饰的变量已分配好了内存,赋过了初值
1.1 运行时数据区概述
JVM的运行时数据区主要由方法区,堆,程序计数器,本地方法栈,虚拟机栈组成,其中一些随着虚拟机启动而创建,随着虚拟机退出而销毁,即它们的生命周期是整个JVM进程,而其它一些是与线程对应的,这些区域会随着线程的开始和结束而创建或销毁
生命周期为进程的数据区域
方法区,堆
生命周期为线程的数据区域
程序计数器(PCR),本地方法栈(NMS),虚拟机栈(VMS)
即一个JVM进程中有5个线程在工作,那么此刻就存在
1个堆,1个方法区,5个PCR,5个VMS,5个NMS
1.2 程序计数器 PC Register
1.2.1 程序计数器简介
JVM中的程序计数寄存器(Program Counter Register)中,Register命名源于CPU中的寄存器,寄存器的工作是存储指令相关的信息,CPU只有把数据装载到寄存器才能运行,运行时数据区中的程序计数寄存器,并不是真实的物理寄存器,JVM中的PC寄存器是对物理PC寄存器的一种抽象模拟
程序计数器是一块很小的内存空间,也是运行速度最快的存储区域,在JVM中,每个进程有若干个线程,每个线程都有自己的程序计数器,是线程私有的,它的生命周期伴随着整个线程
1.2.2 程序计数器作用
任何时间一个线程某一时刻只有一个方法在执行,也就是当前方法,程序计数器会存储当前线程正在执行的当前方法的JVM指令地址,如果在执行本地方法,则存储未指定值(undefined)
程序计数器的作用:
1,它是程序控制流的指示器,分支,循环,跳转,异常处理等基础功能
都需要依赖这个程序计数器来完成
2,字节码解释器工作时,就是通过读取程序计数器的值
来选择下一条需要执行的字节码指令
对于上述的简单程序,编译后通过javap -v反编译后查看:
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
上述的0,2,3,5…就是程序计数器中存储的指令地址,根据这些指令地址,就可以执行当前方法中对应的操作指令,执行当前方法
程序计数器就是用来存储当前方法的指令地址,执行引擎根据程序计数器中的指令地址找到对应的操作指令并执行,且使用操作数栈更新局部变量表